From 8d2cfcfde3c64a41cc0bd0c1c0b381768c940090 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sat, 22 Aug 2026 15:55:01 +0300 Subject: [PATCH 01/23] Check build hints at compile time instead of shipping them inert A build hint is a `codename1.arg.=` line that reaches a builder as `request.getArg(name, default)`. Nothing checked the name, so a misspelling was accepted, copied into the build request, never read, and silently discarded: a green build with the setting simply not applied. Our own agent reference had been shipping `android.xPermissions`, `android.minSdkVersion` and `android.sdkVersion` for exactly that reason. The builders read `android.xpermissions`, `android.min_sdk_version`, and nothing at all. Most hints can now be written as annotations on the application's main class, where javac does the checking: a misspelled name is an unknown symbol, a wrong value type is a type error, and a value outside a hint's supported set is an unknown enum constant. @Ios(newStorageLocation = true, themeMode = IosThemeMode.MODERN) @Android(minSdkVersion = 24, useAndroidX = true) @Desktop(titleBar = DesktopTitleBar.NATIVE) public class MyApplication extends Lifecycle { } The builders are untouched: `BuildHintAnnotationProcessor` converts the annotations back into the same key/value pairs and `CN1BuildMojo` merges them before the command-line overlay, the CN1Lib merges and both preflights, so a library still appends onto an annotation-supplied value and `-D` still wins. `Simulator` publishes them as system properties at startup so `cn1:run` sees hints that no longer live in the properties file. The properties file is untouched too. It stays the way to set the long tail and the open-ended families such as `android.permission.` that an annotation cannot express, with no new warnings or errors. Declaring one hint both ways is a build error. One catalog, five generated views --------------------------------- The hint set had been described in five places that had drifted apart: a prose table in the developer guide, a runtime scraper of that table in the Settings tool that guessed each type by string-matching the description, a fifteen-entry schema in the simulator, a fourteen-entry separator map in the plugin, and a hand-written agent reference. Only 147 of ~520 names appeared in more than one. `maven/build-hint-catalog` is now the single source of truth (529 hints: 457 mined from the builders, 56 documented-but-unread, 16 dynamic families; 82 exposed as annotation attributes). The annotations, the binding table the processor reads back, the guide's table, the simulator's editor schema and the agent reference are all generated from it. The guide's table goes from 208 rows to 529 with no prose lost. Enums are emitted only where the accepted set is demonstrable from the code that reads the hint -- `HardeningPreflight` rejects an unknown `harden.level`, `IOSDependencyManager` throws on an unknown `ios.dependencyManager`, and `GenerateDesktopAppWrapperMojo` silently falls back to `native` on an unknown `desktop.titleBar`, which is the failure this removes. Generated projects ------------------ The archetype and all four initializr templates now carry the annotations, and `cn1:migrate-build-hints` moves an existing project over. Eleven in-repo projects are migrated. `java.version` deliberately stays in the properties file: it picks the toolchain that compiles the class the annotations live on. Gates ----- `scripts/check-build-hint-catalog.sh` fails when code reads a hint the catalog does not describe, and when our own docs or templates name one that no builder reads. Its baseline is empty, so it is a hard gate rather than a ratchet. `scripts/gen-build-hint-annotations.sh --check` fails on generated-file drift. Both run in the Java 8 leg of PR CI. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/pr.yml | 14 + CLAUDE.md | 38 + .../annotations/buildhints/Android.java | 160 + .../buildhints/AndroidThemeMode.java | 49 + .../annotations/buildhints/Build.java | 64 + .../annotations/buildhints/Desktop.java | 72 + .../buildhints/DesktopTitleBar.java | 48 + .../buildhints/HardenControlFlow.java | 47 + .../annotations/buildhints/HardenLevel.java | 49 + .../annotations/buildhints/HardenStrings.java | 48 + .../annotations/buildhints/Hardening.java | 69 + .../buildhints/InstallLocation.java | 48 + .../codename1/annotations/buildhints/Ios.java | 166 + .../buildhints/IosDependencyManager.java | 50 + .../annotations/buildhints/IosPrivacy.java | 112 + .../buildhints/IosProjectType.java | 48 + .../annotations/buildhints/IosThemeMode.java | 49 + .../buildhints/NativeThemeMode.java | 48 + .../annotations/buildhints/OnDeviceDebug.java | 77 + .../annotations/buildhints/package-info.java | 52 + .../impl/javase/BuildHintCatalogDefaults.java | 307 ++ .../impl/javase/BuildHintSchemaDefaults.java | 6 + .../com/codename1/impl/javase/Simulator.java | 66 + .../common/codenameone_settings.properties | 1 - .../codenameone/developerguide/DemoCode.java | 2 + .../Advanced-Topics-Under-The-Hood.asciidoc | 718 +--- .../_generated-build-hints.adoc | 3187 +++++++++++++++++ maven/build-hint-catalog/pom.xml | 31 + .../common/codenameone_settings.properties | 27 +- .../common/src/main/java/__mainName__.java | 13 + maven/codenameone-maven-plugin/pom.xml | 5 + .../com/codename1/maven/CN1BuildMojo.java | 107 + .../codename1/maven/LibraryHintMerger.java | 51 +- .../maven/MigrateBuildHintsMojo.java | 505 +++ .../com/codename1/maven/OpenSettingsMojo.java | 8 +- .../maven/ProcessAnnotationsMojo.java | 56 +- .../maven/annotations/ProcessorContext.java | 35 + .../BuildHintAnnotationProcessor.java | 428 +++ ...ame1.maven.annotations.AnnotationProcessor | 1 + .../BuildHintAnnotationProcessorTest.java | 343 ++ maven/integration-tests/all.sh | 1 + .../build-hint-annotations-test.sh | 93 + maven/pom.xml | 1 + scripts/build-hint-catalog-baseline.txt | 8 + scripts/build_hint_miner.py | 100 + .../common/codenameone_settings.properties | 6 - .../certificatewizard/CertificateWizard.java | 5 + scripts/check-build-hint-catalog.py | 163 + scripts/check-build-hint-catalog.sh | 24 + .../common/codenameone_settings.properties | 5 - .../codenameone/playground/CN1Playground.java | 5 + .../common/codenameone_settings.properties | 4 - .../com/codenameone/fidelity/FidelityApp.java | 3 + .../common/codenameone_settings.properties | 8 +- .../codename1/gamebuilder/GameBuilder.java | 5 + scripts/gen-build-hint-annotations.sh | 55 + .../common/codenameone_settings.properties | 5 - .../guibuilder/CodenameOneGUIBuilder.java | 3 + .../common/codenameone_settings.properties | 7 - .../hellocodenameone/HelloCodenameOne.kt | 4 + .../src/main/resources/barebones-src.zip | Bin 1327 -> 1435 bytes .../common/src/main/resources/common.zip | Bin 251573 -> 251603 bytes .../common/src/main/resources/grub-src.zip | Bin 279805 -> 275075 bytes .../common/src/main/resources/kotlin-src.zip | Bin 1507 -> 1563 bytes .../common/src/main/resources/skill/SKILL.md | 2 +- .../skill/references/android-to-cn1.md | 2 +- .../skill/references/build-and-run.md | 26 +- .../resources/skill/references/build-hints.md | 191 +- .../skill/references/mobile-adaptability.md | 2 +- .../skill/references/native-interfaces.md | 31 +- .../common/src/main/resources/tweet-src.zip | Bin 357703 -> 356080 bytes .../common/codenameone_settings.properties | 3 - .../inputvalidation/InputValidationApp.java | 3 + .../common/codenameone_settings.properties | 6 - .../purchasetest/PurchaseTestApp.java | 4 + .../common/codenameone_settings.properties | 7 - scripts/settings/common/pom.xml | 20 +- .../settings/CodenameOneSettings.java | 57 +- .../settings/hints/BuildHintCatalog.java | 207 +- .../settings/hints/BuildHintMetadata.java | 40 + .../settings/project/ProjectBinding.java | 6 - .../settings/BuildHintCatalogTest.java | 105 +- .../codename1/settings/SettingsThemeTest.java | 7 +- scripts/settings/pom.xml | 5 + .../common/codenameone_settings.properties | 3 - .../codename1/videobuilder/VideoBuilder.java | 2 + tools/build-hint-bootstrap/README.md | 23 + tools/build-hint-bootstrap/curation.py | 220 ++ tools/build-hint-bootstrap/gen_catalog.py | 267 ++ tools/build-hint-bootstrap/gen_external.py | 66 + 90 files changed, 7880 insertions(+), 1135 deletions(-) create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/Android.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/AndroidThemeMode.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/Build.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/Desktop.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/DesktopTitleBar.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/HardenControlFlow.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/HardenLevel.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/HardenStrings.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/Hardening.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/InstallLocation.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/Ios.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/IosDependencyManager.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/IosPrivacy.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/IosProjectType.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/IosThemeMode.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/NativeThemeMode.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java create mode 100644 CodenameOne/src/com/codename1/annotations/buildhints/package-info.java create mode 100644 Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java create mode 100644 docs/developer-guide/_generated-build-hints.adoc create mode 100644 maven/build-hint-catalog/pom.xml create mode 100644 maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java create mode 100644 maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/processors/BuildHintAnnotationProcessor.java create mode 100644 maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java create mode 100755 maven/integration-tests/build-hint-annotations-test.sh create mode 100644 scripts/build-hint-catalog-baseline.txt create mode 100644 scripts/build_hint_miner.py create mode 100755 scripts/check-build-hint-catalog.py create mode 100755 scripts/check-build-hint-catalog.sh create mode 100755 scripts/gen-build-hint-annotations.sh create mode 100644 tools/build-hint-bootstrap/README.md create mode 100644 tools/build-hint-bootstrap/curation.py create mode 100644 tools/build-hint-bootstrap/gen_catalog.py create mode 100644 tools/build-hint-bootstrap/gen_external.py diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index dcc8f9990c1..e70275e9810 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -416,6 +416,20 @@ jobs: - name: Run SpotBugs for ByteCodeTranslator if: ${{ matrix.java-version == 8 }} run: mvn -B -DskipTests=true -f vm/ByteCodeTranslator/pom.xml verify + # A build hint is a string nothing checks: a misspelled name is accepted, + # never read, and silently does nothing. The catalog in + # maven/build-hint-catalog is what gives every hint a type, a default and a + # value domain, and it is what the @Ios/@Android annotations, the developer + # guide table and the Settings tool are generated from. These two steps keep + # the catalog complete and the generated files in step with it. + - name: Check build hint catalog + if: ${{ matrix.java-version == 8 }} + run: scripts/check-build-hint-catalog.sh + - name: Check generated build hint annotations + if: ${{ matrix.java-version == 8 }} + run: | + git config --global --add safe.directory "$GITHUB_WORKSPACE" + scripts/gen-build-hint-annotations.sh --check # ParparVM's CHECKCAST is unchecked, so a failed cast does not throw # ClassCastException on iOS -- code written to catch it silently uses the # wrong object instead (issue #5531). core/android/ios are already compiled diff --git a/CLAUDE.md b/CLAUDE.md index 3ec43bd914a..fef8739422a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -213,6 +213,44 @@ removing one can make a previously-used private method dead. Findings land in each module's `target/spotbugsXml.xml`. +### Build hints are a catalog, not free-form strings + +A build hint is a `codename1.arg.=` line that reaches a builder as +`request.getArg(name, default)`. Nothing used to check the name, so a misspelled +hint was accepted, never read, and silently did nothing -- a green build with the +setting simply not applied. Our own agent reference shipped +`android.xPermissions`, `android.minSdkVersion` and `android.sdkVersion` for +years; the builders read `android.xpermissions`, `android.min_sdk_version`, and +nothing at all. + +**`maven/build-hint-catalog` is the single source of truth.** Every hint's name, +type, default, value domain, merge separator and documentation lives there, and +everything else is generated from it: + +- the `com.codename1.annotations.buildhints` annotations in `CodenameOne/src` +- `BuildHintAnnotationBinding`, which the annotation processor reads back +- the developer guide's build hint table (`docs/developer-guide/_generated-build-hints.adoc`) +- the simulator's Build Hint editor schema (`BuildHintCatalogDefaults`) +- the agent reference's annotation table (`skill/references/build-hints.md`) + +Adding a hint to a builder means adding it to the catalog in the same change. +Regenerate with: + +```bash +source tools/env.sh +scripts/gen-build-hint-annotations.sh # rewrite the generated files +scripts/gen-build-hint-annotations.sh --check # what CI runs +scripts/check-build-hint-catalog.sh # every hint the code reads is catalogued +``` + +`scripts/build-hint-catalog-baseline.txt` is a ratchet, and it is **empty**: every +hint the code reads is described. A new entry means a hint went in without a +catalog row. The same gate refuses a `codename1.arg.*` key in our own docs and +project templates that no builder reads. + +Do not re-run `tools/build-hint-bootstrap/` -- it seeded the catalog once and +would overwrite hand edits. + ### Never rely on ClassCastException **ParparVM's `CHECKCAST` is unchecked.** `BC_CHECKCAST` expands to nothing and the diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/Android.java b/CodenameOne/src/com/codename1/annotations/buildhints/Android.java new file mode 100644 index 00000000000..a308905c7fe --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/Android.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/// Android build hints, checked by the compiler. +/// +/// Place this on your application's main class -- the class named by +/// `codename1.mainName`. An attribute you do not set is not written at all, so +/// the builder's own default applies; the values shown here are that default, +/// for reference. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.TYPE) +public @interface Android { + + /// Allows explicitly setting the `android:launchMode` attribute of the main + /// activity in android. Default is "singleTop," but for some applications you + /// may need to change this behaviour. In particular, apps that are meant to + /// open a file type will need to set this to "singleTask." See + /// https://developer.android.com/guide/topics/manifest/activity-element.html[Android + /// docs for the activity element] for more information about the + /// `android:launchMode` attribute. + String activityLaunchMode() default "singleTop"; + + /// Produces an Android App Bundle (.aab) rather than an APK. Required for new + /// Play Store submissions. + boolean appBundle() default false; + + /// Android build-tools version. It also selects the compile SDK, so there is no + /// separate compile-SDK hint. + String buildToolsVersion() default ""; + + /// Indicates whether the `RECORD_AUDIO` permission should be requested. Can be + /// `enabled` or any other value to disable this option + String captureRecord() default "enabled"; + + /// true/false defaults to true - indicates whether to include the debug version + /// in the build. Defaults conditionally rather than to a fixed value: when + /// android.release is on it defaults to false, and when release is off it + /// defaults to true, so a build that selects neither still produces something + /// installable (AndroidGradleBuilder.java:447-451). + boolean debug() default false; + + /// Turns off R8, falling back to the older shrinker. Note that hardening + /// requires R8, so this conflicts with harden.level. + boolean disableR8() default false; + + /// Boolean true/false defaults to true. Allows disabling the proguard + /// obfuscation even on release builds, notice that this isn't recommended + boolean enableProguard() default true; + + /// Gradle dependency statements to add to the app module, such as + /// implementation 'com.example:lib:1.0'. + /// Values are joined with `;` when the hint is written. + String[] gradleDep() default {}; + + /// Hides the Android status bar. + boolean hideStatusBar() default false; + + /// Maps to android:installLocation manifest entry defaults to auto. Can also be + /// set to internalOnly or preferExternal. + InstallLocation installLocation() default InstallLocation.AUTO; + + /// The license key for the Android app, this is required if you use in-app + /// purchase on Android + String licenseKey() default ""; + + /// The least SDK required to run this app, the default value changes based on + /// functionality but can be as low as 7. This corresponds to the XML attribute + /// `android:minSdkVersion`. + int minSdkVersion() default 19; + + /// Boolean true/false defaults to false. Multidex allows Android binaries to + /// reference more than 65536 methods. This slows builds a bit so you have it + /// off by default but if you get a build error mentioning this limit you should + /// turn this on. + boolean multidex() default true; + + /// Uses the current Firebase Cloud Messaging integration. Requires AndroidX and + /// Gradle 8.13 or newer. + boolean newFirebaseMessaging() default true; + + /// Arguments for the keep option in proguard allowing you to keep a pattern of + /// files for example, `-keep class com.mypackage.ProblemClass { *; }` + /// Values are joined with `\n` when the hint is written. + String[] proguardKeep() default {}; + + /// true/false defaults to true - indicates whether to include the release + /// version in the build + boolean release() default true; + + /// Extra Gradle repositories to resolve dependencies from. + /// Values are joined with `\n` when the hint is written. + String[] repositories() default {}; + + /// Indicates the Android SDK used to compile the Android build defaults to 21. + /// Notice that not all targets will work since the source might have some + /// limitations and not all SDK targets are installed on the build servers. + int targetSDKVersion() default 0; + + /// `auto`, `modern` / `material`, `hololight` (default for existing apps), + /// `legacy`. `auto` and `modern` / `material` opt in to the CSS-generated + /// Android Material 3 theme from `native-themes/android-material/theme.css`. + /// `hololight` is Android Holo Light (what the framework shipped on API 14+ + /// before this refactor). `legacy` loads the pre-Holo Android theme. The legacy + /// alias `cn1.androidTheme` is still accepted, and `and.hololight=true` still + /// maps to `hololight`. The default stays on `hololight` for existing apps + /// until you flip in a future release. + AndroidThemeMode themeMode() default AndroidThemeMode.AUTO; + + /// Statements added to the top-level Gradle build file rather than the app + /// module. + /// Values are joined with `\n` when the hint is written. + String[] topDependency() default {}; + + /// Use Android X instead of support libraries. This will also run a + /// find/replace on all source files to replace support libraries and artifacts + /// with AndroidX equivalents. + boolean useAndroidX() default false; + + /// defaults to an empty string. Allows developers of native Android code to add + /// text within the application block to define things such as widgets, services + /// etc. + String xapplication() default ""; + + /// Arbitrary text spliced into the generated app-module Gradle file. + /// Values are joined with `\n` when the hint is written. + String[] xgradle() default {}; + + /// more permissions for the Android manifest + String xpermissions() default ""; +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/AndroidThemeMode.java b/CodenameOne/src/com/codename1/annotations/buildhints/AndroidThemeMode.java new file mode 100644 index 00000000000..0fb0d887471 --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/AndroidThemeMode.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +/// Accepted values of the `and.themeMode` build hint. +/// +/// Each constant carries the string the build actually receives, which is not +/// always the constant's own name. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +public enum AndroidThemeMode { + AUTO("auto"), + MODERN("modern"), + HOLOLIGHT("hololight"), + LEGACY("legacy"); + + private final String wire; + + AndroidThemeMode(String wire) { + this.wire = wire; + } + + /// The value written into the build hint. + public String wireValue() { + return wire; + } +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/Build.java b/CodenameOne/src/com/codename1/annotations/buildhints/Build.java new file mode 100644 index 00000000000..031fac834db --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/Build.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/// Build hints that are not specific to one platform. +/// +/// Place this on your application's main class -- the class named by +/// `codename1.mainName`. An attribute you do not set is not written at all, so +/// the builder's own default applies; the values shown here are that default, +/// for reference. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.TYPE) +public @interface Build { + + /// The application ID for an app that requires native Facebook login + /// integration, this defaults to null which means native Facebook support + /// shouldn't be in the app + String facebookAppId() default "706695982682332"; + + /// The Android/chrome push identifier, see the push section for more details + String gcmSenderId() default ""; + + /// `modern`, `legacy`, `custom` (default unset). Cross-platform override that + /// sets both `ios.themeMode` and `and.themeMode` together when those aren't set + /// explicitly. `modern` = liquid glass + Material 3, `legacy` = iOS 7 flat + + /// Holo Light, `custom` disables the framework native theme entirely. The + /// legacy alias `cn1.nativeTheme` is still accepted. + NativeThemeMode nativeTheme() default NativeThemeMode.MODERN; + + /// true/false (defaults to false). Blocks codename one from injecting its own + /// resources when set to true, the only effect this has is in slightly reducing + /// archive size. This might have adverse effects on some features of Codename + /// One so it isn't recommended. + boolean noExtraResources() default false; +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/Desktop.java b/CodenameOne/src/com/codename1/annotations/buildhints/Desktop.java new file mode 100644 index 00000000000..d8fcae1c401 --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/Desktop.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/// Desktop build hints, checked by the compiler. +/// +/// Place this on your application's main class -- the class named by +/// `codename1.mainName`. An attribute you do not set is not written at all, so +/// the builder's own default applies; the values shown here are that default, +/// for reference. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.TYPE) +public @interface Desktop { + + /// Boolean true/false defaults to true. When set to true some values will ve + /// implicitly doubled to deal with retina displays and icons etc. Will use + /// higher DPI's + boolean adaptToRetina() default true; + + /// Starts the desktop build in full-screen mode. + boolean fullscreen() default false; + + /// Height in pixels for the form in desktop builds, will be doubled for retina + /// grade displays. Defaults to 600. + int height() default 600; + + /// Enables grab-able, click-to-page desktop scrollbars. + boolean interactiveScrollbars() default true; + + /// Boolean true/false defaults to true. Indicates whether the UI in the desktop + /// build is resizable + boolean resizable() default true; + + /// How the desktop window is framed: native for the OS title bar and menu bar, + /// custom for an undecorated window with a Codename One drawn title bar, or + /// toolbar for the legacy in-app Toolbar. An unrecognized value falls back to + /// native with a warning. + DesktopTitleBar titleBar() default DesktopTitleBar.NATIVE; + + /// Width in pixels for the form in desktop builds, will be doubled for retina + /// grade displays. Defaults to 800. + int width() default 800; +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/DesktopTitleBar.java b/CodenameOne/src/com/codename1/annotations/buildhints/DesktopTitleBar.java new file mode 100644 index 00000000000..b9da214763c --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/DesktopTitleBar.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +/// Accepted values of the `desktop.titleBar` build hint. +/// +/// Each constant carries the string the build actually receives, which is not +/// always the constant's own name. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +public enum DesktopTitleBar { + NATIVE("native"), + CUSTOM("custom"), + TOOLBAR("toolbar"); + + private final String wire; + + DesktopTitleBar(String wire) { + this.wire = wire; + } + + /// The value written into the build hint. + public String wireValue() { + return wire; + } +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/HardenControlFlow.java b/CodenameOne/src/com/codename1/annotations/buildhints/HardenControlFlow.java new file mode 100644 index 00000000000..3e10121724d --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/HardenControlFlow.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +/// Accepted values of the `harden.controlFlow` build hint. +/// +/// Each constant carries the string the build actually receives, which is not +/// always the constant's own name. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +public enum HardenControlFlow { + OFF("off"), + ON("on"); + + private final String wire; + + HardenControlFlow(String wire) { + this.wire = wire; + } + + /// The value written into the build hint. + public String wireValue() { + return wire; + } +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/HardenLevel.java b/CodenameOne/src/com/codename1/annotations/buildhints/HardenLevel.java new file mode 100644 index 00000000000..ae32518c1be --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/HardenLevel.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +/// Accepted values of the `harden.level` build hint. +/// +/// Each constant carries the string the build actually receives, which is not +/// always the constant's own name. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +public enum HardenLevel { + OFF("off"), + STANDARD("standard"), + AGGRESSIVE("aggressive"), + PARANOID("paranoid"); + + private final String wire; + + HardenLevel(String wire) { + this.wire = wire; + } + + /// The value written into the build hint. + public String wireValue() { + return wire; + } +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/HardenStrings.java b/CodenameOne/src/com/codename1/annotations/buildhints/HardenStrings.java new file mode 100644 index 00000000000..15f866cd08d --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/HardenStrings.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +/// Accepted values of the `harden.strings` build hint. +/// +/// Each constant carries the string the build actually receives, which is not +/// always the constant's own name. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +public enum HardenStrings { + OFF("off"), + CONSTANTS("constants"), + ALL("all"); + + private final String wire; + + HardenStrings(String wire) { + this.wire = wire; + } + + /// The value written into the build hint. + public String wireValue() { + return wire; + } +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/Hardening.java b/CodenameOne/src/com/codename1/annotations/buildhints/Hardening.java new file mode 100644 index 00000000000..c9190a591fd --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/Hardening.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/// App hardening build hints, checked by the compiler. +/// +/// Place this on your application's main class -- the class named by +/// `codename1.mainName`. An attribute you do not set is not written at all, so +/// the builder's own default applies; the values shown here are that default, +/// for reference. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.TYPE) +public @interface Hardening { + + /// Permits a local or source build to run with hardening requested but not + /// applied. Without it such a build is refused, so a hardened app is never + /// shipped from a target that cannot actually harden it. + boolean allowUnhardenedLocalBuild() default false; + + /// Overrides control-flow obfuscation independently of harden.level. + HardenControlFlow controlFlow() default HardenControlFlow.OFF; + + /// Keep rules in ProGuard syntax, one per line, for classes that are resolved + /// by name at runtime and so cannot be found by the automatic analysis. Same + /// syntax as android.proguardKeep, so existing rules port directly. Rules are + /// separated by newlines only, because a semicolon is legal inside a rule body + /// such as { *; }. + String keep() default ""; + + /// Master switch for app hardening: off, standard, aggressive or paranoid. An + /// unrecognized value fails the build rather than being quietly treated as off. + HardenLevel level() default HardenLevel.OFF; + + /// Overrides symbol renaming independently of harden.level. + boolean rename() default false; + + /// Overrides string obfuscation independently of harden.level: off, constants + /// or all. + HardenStrings strings() default HardenStrings.OFF; +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/InstallLocation.java b/CodenameOne/src/com/codename1/annotations/buildhints/InstallLocation.java new file mode 100644 index 00000000000..a1c7655fa57 --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/InstallLocation.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +/// Accepted values of the `android.installLocation` build hint. +/// +/// Each constant carries the string the build actually receives, which is not +/// always the constant's own name. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +public enum InstallLocation { + AUTO("auto"), + INTERNAL_ONLY("internalOnly"), + PREFER_EXTERNAL("preferExternal"); + + private final String wire; + + InstallLocation(String wire) { + this.wire = wire; + } + + /// The value written into the build hint. + public String wireValue() { + return wire; + } +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/Ios.java b/CodenameOne/src/com/codename1/annotations/buildhints/Ios.java new file mode 100644 index 00000000000..081b7a871bf --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/Ios.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/// iOS build hints, checked by the compiler. +/// +/// Place this on your application's main class -- the class named by +/// `codename1.mainName`. An attribute you do not set is not written at all, so +/// the builder's own default applies; the values shown here are that default, +/// for reference. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.TYPE) +public @interface Ios { + + /// A semicolon separated list of libraries that should be linked to the app to + /// build it + /// Values are joined with `;` when the hint is written. + String[] addLibs() default {}; + + /// Comma separated list of url schemes that `canExecute` will respect on iOS. + /// If the url scheme isn't mentioned here `canExecute` will return false + /// starting with iOS 9. Notice that this collides with `ios.plistInject` when + /// used with the `LSApplicationQueriesSchemes...` value so you + /// should use one or the other. For example, to enable `canExecute` for a url + /// like `myurl://xys` you can use: `myurl,myotherurl` + /// Values are joined with `,` when the hint is written. + String[] applicationQueriesSchemes() default {}; + + /// Objective-C code that can be injected into the iOS app delegate at the top + /// of the body of the didFinishLaunchingWithOptions callback method + String beforeFinishLaunching() default ""; + + /// Indicates the version number of the bundle, this is useful if you want to + /// create a minor version number change for the beta testing support + String bundleVersion() default ""; + + /// Which native dependency manager to use: auto picks one from whichever of + /// ios.pods and ios.spm.packages is set, and cocoapods, spm or both require the + /// matching hint to be set. An unrecognized value fails the build. + IosDependencyManager dependencyManager() default IosDependencyManager.AUTO; + + /// Minimum iOS version the build targets. Set it to the lowest iOS you actually + /// support; a higher value excludes older devices from the App Store listing. + String deploymentTarget() default ""; + + /// Objective-C code that can be injected into the iOS app delegate at the top + /// of the file. For example, if you need to include headers or make special + /// imports for other injected code + String glAppDelegateHeader() default ""; + + /// true/false (defaults to false). Whether to include the push capabilities in + /// the iOS build. Notice that the IDE plugin has an "Include Push" check box + /// you *should* use under the iOS section. + boolean includePush() default false; + + /// UIInterfaceOrientationPortrait by default. Indicates the orientation, one or + /// more of (separated by colon :): `UIInterfaceOrientationPortrait`, + /// `UIInterfaceOrientationPortraitUpsideDown`, + /// `UIInterfaceOrientationLandscapeLeft`, + /// `UIInterfaceOrientationLandscapeRight`. Notice that the IDE plugin has an + /// "Interface Orientation" combo box you *should* use under the iOS section. + String interfaceOrientation() default ""; + + /// The null and empty-string reads of this hint are presence checks; 6.0 is the + /// substantive default (IPhoneBuilder.java:4671). + String minDeploymentTarget() default "6.0"; + + /// true/false defaults to false but defined on new projects as true by default. + /// This changes the storage directory on iOS from using caches to using the + /// documents directory which is the recommended location but might break + /// compatibility. This is described in + /// https://github.com/codenameone/CodenameOne/issues/1480[this issue] + boolean newStorageLocation() default true; + + /// Added the `-ObjC` compile flag to the project files which some native + /// libraries require + boolean objC() default false; + + /// entries to inject into the iOS plist file during build. + String plistInject() default ""; + + /// A comma separated list of https://cocoapods.org/[Cocoa Pods] that should be + /// linked to the app to build it. For example, `AFNetworking ~> 2.6, + /// ORStackView ~> 3.0, SwiftyJSON ~> 2.3` + /// Values are joined with `,` when the hint is written. + String[] pods() default {}; + + /// Sets the Cocoapods 'platform' for the Cocoapods. Some Cocoapods require a + /// minimum platform level. For example, `ios.pods.platform=7.0`. + String podsPlatform() default ""; + + /// Extra CocoaPods spec repositories to search, in addition to the default + /// trunk. + /// Values are joined with `,` when the hint is written. + String[] podsSources() default {}; + + /// true/false defaults to false. The iOS build process adapts the submitted + /// icon for iOS conventions (adding an overlay) that might not be appropriate + /// on some icons. Setting this to true leaves the icon unchanged (only scaled). + boolean prerenderedIcon() default false; + + /// one of ios, ipad, iphone (defaults to ios). Indicates whether the resulting + /// binary is targeted to the iphone only or ipad only. Notice that the IDE + /// plugin has a "Project Type" combo box you *should* use under the iOS + /// section. + IosProjectType projectType() default IosProjectType.IOS; + + /// Swift Package Manager packages to link, one per entry, each written as + /// identity|url|requirement. + /// Values are joined with `;` when the hint is written. + String[] spmPackages() default {}; + + /// Specifies the team ID associated with the iOS provisioning profile and + /// certificate. Use `ios.debug.teamId` and `ios.release.teamId` to specify + /// different team IDs for debug and release builds respectively. + String teamId() default ""; + + /// `auto` (default), `modern`, `ios7`, `legacy`. `auto` (unset) keeps the + /// existing iOS 7 flat theme so pre-refactor screenshot goldens and apps see no + /// behavior change. `modern` / `liquid` opts in to the CSS-generated iOS Modern + /// (liquid-glass) theme shipped from `native-themes/ios-modern/theme.css`. + /// `ios7` / `flat` is the same as `auto` - pre-liquid iOS 7 flat theme; + /// `legacy` / `iphone` loads the pre-iOS 7 iPhone theme. The `auto` -> modern + /// flip is planned for a future release. + IosThemeMode themeMode() default IosThemeMode.AUTO; + + /// true/false (defaults to true). Enables iOS UIScene lifecycle support. + /// UIScene lets iOS manage one or more app UI sessions independently, improving + /// lifecycle handling in modern iOS versions. Apple has indicated UIScene will + /// be required starting with iOS 27, so this is now on by default; set the flag + /// to `false` only if you need to temporarily fall back to the legacy + /// `UIApplicationDelegate` lifecycle. + boolean uiscene() default true; + + /// Allows intercepting a URL call using the syntax `urlPrefix` + String urlScheme() default ""; +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/IosDependencyManager.java b/CodenameOne/src/com/codename1/annotations/buildhints/IosDependencyManager.java new file mode 100644 index 00000000000..d30fa80f9ba --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/IosDependencyManager.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +/// Accepted values of the `ios.dependencyManager` build hint. +/// +/// Each constant carries the string the build actually receives, which is not +/// always the constant's own name. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +public enum IosDependencyManager { + AUTO("auto"), + COCOAPODS("cocoapods"), + SPM("spm"), + BOTH("both"), + NONE("none"); + + private final String wire; + + IosDependencyManager(String wire) { + this.wire = wire; + } + + /// The value written into the build hint. + public String wireValue() { + return wire; + } +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/IosPrivacy.java b/CodenameOne/src/com/codename1/annotations/buildhints/IosPrivacy.java new file mode 100644 index 00000000000..0375ac2116a --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/IosPrivacy.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/// iOS `Info.plist` privacy usage descriptions. Set the one for every protected +/// resource your app touches: the build server accepts an app without them, and +/// the App Store rejects it. +/// +/// Place this on your application's main class -- the class named by +/// `codename1.mainName`. An attribute you do not set is not written at all, so +/// the builder's own default applies; the values shown here are that default, +/// for reference. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.TYPE) +public @interface IosPrivacy { + + /// The text iOS shows when the app first asks for the calendars full access. It + /// becomes the `NSCalendarsFullAccessUsageDescription` key in `Info.plist`. The + /// App Store rejects an app that touches this resource without one. + String calendarsFullAccessUsageDescription() default "This app uses your calendars to read and schedule events."; + + /// The text iOS shows when the app first asks for the calendars. It becomes the + /// `NSCalendarsUsageDescription` key in `Info.plist`. The App Store rejects an + /// app that touches this resource without one. + String calendarsUsageDescription() default ""; + + /// The text iOS shows when the app first asks for the calendars write only + /// access. It becomes the `NSCalendarsWriteOnlyAccessUsageDescription` key in + /// `Info.plist`. The App Store rejects an app that touches this resource + /// without one. + String calendarsWriteOnlyAccessUsageDescription() default "This app uses your calendar to schedule events."; + + /// The text iOS shows when the app first asks for the camera. It becomes the + /// `NSCameraUsageDescription` key in `Info.plist`. The App Store rejects an app + /// that touches this resource without one. + String cameraUsageDescription() default ""; + + /// The text iOS shows when the app first asks for the health share. It becomes + /// the `NSHealthShareUsageDescription` key in `Info.plist`. The App Store + /// rejects an app that touches this resource without one. + String healthShareUsageDescription() default ""; + + /// The text iOS shows when the app first asks for the health update. It becomes + /// the `NSHealthUpdateUsageDescription` key in `Info.plist`. The App Store + /// rejects an app that touches this resource without one. + String healthUpdateUsageDescription() default ""; + + /// The text iOS shows when the app first asks for the local network. It becomes + /// the `NSLocalNetworkUsageDescription` key in `Info.plist`. The App Store + /// rejects an app that touches this resource without one. + String localNetworkUsageDescription() default ""; + + /// The text iOS shows when the app first asks for the location always and when + /// in use. It becomes the `NSLocationAlwaysAndWhenInUseUsageDescription` key in + /// `Info.plist`. The App Store rejects an app that touches this resource + /// without one. + String locationAlwaysAndWhenInUseUsageDescription() default ""; + + /// The text iOS shows when the app first asks for the location always. It + /// becomes the `NSLocationAlwaysUsageDescription` key in `Info.plist`. The App + /// Store rejects an app that touches this resource without one. + String locationAlwaysUsageDescription() default ""; + + /// The text iOS shows when the app first asks for the location when in use. It + /// becomes the `NSLocationWhenInUseUsageDescription` key in `Info.plist`. The + /// App Store rejects an app that touches this resource without one. + String locationWhenInUseUsageDescription() default ""; + + /// The text iOS shows when the app first asks for the microphone. It becomes + /// the `NSMicrophoneUsageDescription` key in `Info.plist`. The App Store + /// rejects an app that touches this resource without one. + String microphoneUsageDescription() default ""; + + /// The text iOS shows when the app first asks for the reminders full access. It + /// becomes the `NSRemindersFullAccessUsageDescription` key in `Info.plist`. The + /// App Store rejects an app that touches this resource without one. + String remindersFullAccessUsageDescription() default "This app uses your reminders to read and schedule tasks."; + + /// The text iOS shows when the app first asks for the reminders. It becomes the + /// `NSRemindersUsageDescription` key in `Info.plist`. The App Store rejects an + /// app that touches this resource without one. + String remindersUsageDescription() default ""; +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/IosProjectType.java b/CodenameOne/src/com/codename1/annotations/buildhints/IosProjectType.java new file mode 100644 index 00000000000..1e18538ee3b --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/IosProjectType.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +/// Accepted values of the `ios.project_type` build hint. +/// +/// Each constant carries the string the build actually receives, which is not +/// always the constant's own name. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +public enum IosProjectType { + IOS("ios"), + IPAD("ipad"), + IPHONE("iphone"); + + private final String wire; + + IosProjectType(String wire) { + this.wire = wire; + } + + /// The value written into the build hint. + public String wireValue() { + return wire; + } +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/IosThemeMode.java b/CodenameOne/src/com/codename1/annotations/buildhints/IosThemeMode.java new file mode 100644 index 00000000000..ca2a7d24aa7 --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/IosThemeMode.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +/// Accepted values of the `ios.themeMode` build hint. +/// +/// Each constant carries the string the build actually receives, which is not +/// always the constant's own name. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +public enum IosThemeMode { + AUTO("auto"), + MODERN("modern"), + IOS7("ios7"), + LEGACY("legacy"); + + private final String wire; + + IosThemeMode(String wire) { + this.wire = wire; + } + + /// The value written into the build hint. + public String wireValue() { + return wire; + } +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/NativeThemeMode.java b/CodenameOne/src/com/codename1/annotations/buildhints/NativeThemeMode.java new file mode 100644 index 00000000000..7b9f2291ebb --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/NativeThemeMode.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +/// Accepted values of the `nativeTheme` build hint. +/// +/// Each constant carries the string the build actually receives, which is not +/// always the constant's own name. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +public enum NativeThemeMode { + MODERN("modern"), + LEGACY("legacy"), + CUSTOM("custom"); + + private final String wire; + + NativeThemeMode(String wire) { + this.wire = wire; + } + + /// The value written into the build hint. + public String wireValue() { + return wire; + } +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java b/CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java new file mode 100644 index 00000000000..14a467ace1e --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.annotations.buildhints; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/// On-device debugging build hints for iOS and Android. +/// +/// Place this on your application's main class -- the class named by +/// `codename1.mainName`. An attribute you do not set is not written at all, so +/// the builder's own default applies; the values shown here are that default, +/// for reference. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.TYPE) +public @interface OnDeviceDebug { + + /// Boolean true/false defaults to false. When `true`, the generated + /// `AndroidManifest.xml` is marked `android:debuggable="true"`, R8/proguard is + /// disabled, and the build is pinned to debug-only (`android.release` is forced + /// off and `android.debug` is forced on) so a stray hint can't ship a + /// release-signed APK that's `debuggable="true"`. Pair with the + /// `cn1:android-on-device-debugging` Maven goal (or the bundled IntelliJ run + /// configs) to install, launch, forward JDWP, and stream logcat through adb. + /// Has no effect on builds that don't carry it — release builds are unaffected. + /// See the On-Device Debugging (Android) chapter for the full flow. + boolean android() default false; + + /// Boolean true/false defaults to false. When `true`, the iOS build links a + /// small JDWP listener thread (`cn1_debugger`) into the binary and the ParparVM + /// translator emits source-line and locals metadata so a desktop proxy can + /// serve the running app to any JDWP-speaking debugger. Has no effect on + /// release builds. See the On-Device Debugging (iOS) chapter for the full flow. + boolean ios() default false; + + /// Hostname or IP address the device-side listener dials to reach the desktop + /// proxy. Default `127.0.0.1` (correct for the native iOS simulator). For a + /// physical device, set this to the developer laptop's LAN IP. Has no effect + /// unless `ios.onDeviceDebug=true`. + String iosProxyHost() default "127.0.0.1"; + + /// TCP port on `ios.onDeviceDebug.proxyHost` where the proxy is listening for + /// the device. Default `55333`. Has no effect unless `ios.onDeviceDebug=true`. + int iosProxyPort() default 55333; + + /// Boolean true/false defaults to false. When `true`, the app blocks at startup + /// until the proxy connects and the IDE tells the VM to continue. Useful when + /// the breakpoint to investigate fires during app boot. Has no effect unless + /// `ios.onDeviceDebug=true`. + boolean iosWaitForAttach() default false; +} diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/package-info.java b/CodenameOne/src/com/codename1/annotations/buildhints/package-info.java new file mode 100644 index 00000000000..f040888412c --- /dev/null +++ b/CodenameOne/src/com/codename1/annotations/buildhints/package-info.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +/// Build hints expressed as annotations, so the compiler checks them. +/// +/// A build hint used to be a `codename1.arg.=` line in +/// `codenameone_settings.properties`. Nothing validated it, so a misspelled +/// name was copied into the build request, never read, and silently dropped: +/// the build stayed green and the setting simply did nothing. Written as an +/// annotation the same mistake is an unknown symbol, a wrong value type is a +/// type error, and a value outside a hint's supported set is an unknown enum +/// constant. +/// +/// Put the annotations on your application's main class: +/// +/// ```java +/// @Ios(newStorageLocation = true, themeMode = IosThemeMode.MODERN) +/// @Android(themeMode = AndroidThemeMode.MODERN) +/// @Desktop(titleBar = DesktopTitleBar.NATIVE) +/// public class MyApplication { +/// } +/// ``` +/// +/// These annotations cover the hints most applications set. The rest, and the +/// open-ended families such as `android.permission.` that an annotation +/// cannot express, are still set in `codenameone_settings.properties`, which +/// continues to work exactly as before. Setting the same hint in both places is +/// a build error. +/// +/// Generated from com.codename1.build.shared.BuildHints by +/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and +/// re-run scripts/gen-build-hint-annotations.sh. +package com.codename1.annotations.buildhints; diff --git a/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java b/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java new file mode 100644 index 00000000000..477dbc68ce8 --- /dev/null +++ b/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.impl.javase; + +/** + * Build Hint editor schema for every hint that has a build hint annotation. + * + *

Generated from com.codename1.build.shared.BuildHints by + * BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and re-run + * scripts/gen-build-hint-annotations.sh.

+ * + *

Registered after {@link BuildHintSchemaDefaults}, whose hand-written + * entries take precedence because the shared setter never overwrites.

+ */ +final class BuildHintCatalogDefaults { + + private BuildHintCatalogDefaults() { + } + + static void register() { + + set("{{@IosPrivacy}}.label", "iOS Privacy Strings"); + set("{{#IosPrivacy#ios.NSCalendarsFullAccessUsageDescription}}.label", "Calendars full access usage description"); + set("{{#IosPrivacy#ios.NSCalendarsFullAccessUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSCalendarsUsageDescription}}.label", "Calendars usage description"); + set("{{#IosPrivacy#ios.NSCalendarsUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSCalendarsWriteOnlyAccessUsageDescription}}.label", "Calendars write only access usage description"); + set("{{#IosPrivacy#ios.NSCalendarsWriteOnlyAccessUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSCameraUsageDescription}}.label", "Camera usage description"); + set("{{#IosPrivacy#ios.NSCameraUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSHealthShareUsageDescription}}.label", "Health share usage description"); + set("{{#IosPrivacy#ios.NSHealthShareUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSHealthUpdateUsageDescription}}.label", "Health update usage description"); + set("{{#IosPrivacy#ios.NSHealthUpdateUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSLocalNetworkUsageDescription}}.label", "Local network usage description"); + set("{{#IosPrivacy#ios.NSLocalNetworkUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSLocationAlwaysAndWhenInUseUsageDescription}}.label", "Location always and when in use usage description"); + set("{{#IosPrivacy#ios.NSLocationAlwaysAndWhenInUseUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSLocationAlwaysUsageDescription}}.label", "Location always usage description"); + set("{{#IosPrivacy#ios.NSLocationAlwaysUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSLocationWhenInUseUsageDescription}}.label", "Location when in use usage description"); + set("{{#IosPrivacy#ios.NSLocationWhenInUseUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSMicrophoneUsageDescription}}.label", "Microphone usage description"); + set("{{#IosPrivacy#ios.NSMicrophoneUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSRemindersFullAccessUsageDescription}}.label", "Reminders full access usage description"); + set("{{#IosPrivacy#ios.NSRemindersFullAccessUsageDescription}}.type", "TextField"); + set("{{#IosPrivacy#ios.NSRemindersUsageDescription}}.label", "Reminders usage description"); + set("{{#IosPrivacy#ios.NSRemindersUsageDescription}}.type", "TextField"); + + set("{{@Ios}}.label", "iOS"); + set("{{#Ios#ios.add_libs}}.label", "Add libs"); + set("{{#Ios#ios.add_libs}}.type", "TextArea"); + set("{{#Ios#ios.add_libs}}.description", "A semicolon separated list of libraries that should be linked to the app to build it"); + set("{{#Ios#ios.applicationQueriesSchemes}}.label", "Application queries schemes"); + set("{{#Ios#ios.applicationQueriesSchemes}}.type", "TextArea"); + set("{{#Ios#ios.applicationQueriesSchemes}}.description", "Comma separated list of url schemes that `canExecute` will respect on iOS. If the url scheme isn't mentioned here `canExecute` will return false starting with iOS 9. Notice that this collides with `ios.plistInject` when used with the `LSApplicationQueriesSchemes...` value so you should use one or the other. For example, to enable `canExecute` for a url like `myurl://xys` you can use: `myurl,myotherurl`"); + set("{{#Ios#ios.beforeFinishLaunching}}.label", "Before finish launching"); + set("{{#Ios#ios.beforeFinishLaunching}}.type", "TextArea"); + set("{{#Ios#ios.beforeFinishLaunching}}.description", "Objective-C code that can be injected into the iOS app delegate at the top of the body of the didFinishLaunchingWithOptions callback method"); + set("{{#Ios#ios.bundleVersion}}.label", "Bundle version"); + set("{{#Ios#ios.bundleVersion}}.type", "TextField"); + set("{{#Ios#ios.bundleVersion}}.description", "Indicates the version number of the bundle, this is useful if you want to create a minor version number change for the beta testing support"); + set("{{#Ios#ios.dependencyManager}}.label", "Dependency manager"); + set("{{#Ios#ios.dependencyManager}}.type", "Select"); + set("{{#Ios#ios.dependencyManager}}.values", "auto,cocoapods,spm,both,none"); + set("{{#Ios#ios.dependencyManager}}.description", "Which native dependency manager to use: auto picks one from whichever of ios.pods and ios.spm.packages is set, and cocoapods, spm or both require the matching hint to be set. An unrecognized value fails the build."); + set("{{#Ios#ios.deployment_target}}.label", "Deployment target"); + set("{{#Ios#ios.deployment_target}}.type", "TextField"); + set("{{#Ios#ios.deployment_target}}.description", "Minimum iOS version the build targets. Set it to the lowest iOS you actually support; a higher value excludes older devices from the App Store listing."); + set("{{#Ios#ios.glAppDelegateHeader}}.label", "Gl app delegate header"); + set("{{#Ios#ios.glAppDelegateHeader}}.type", "TextArea"); + set("{{#Ios#ios.glAppDelegateHeader}}.description", "Objective-C code that can be injected into the iOS app delegate at the top of the file. For example, if you need to include headers or make special imports for other injected code"); + set("{{#Ios#ios.includePush}}.label", "Include push"); + set("{{#Ios#ios.includePush}}.type", "Checkbox"); + set("{{#Ios#ios.includePush}}.description", "true/false (defaults to false). Whether to include the push capabilities in the iOS build. Notice that the IDE plugin has an \"Include Push\" check box you *should* use under the iOS section."); + set("{{#Ios#ios.interface_orientation}}.label", "Interface orientation"); + set("{{#Ios#ios.interface_orientation}}.type", "TextField"); + set("{{#Ios#ios.interface_orientation}}.description", "UIInterfaceOrientationPortrait by default. Indicates the orientation, one or more of (separated by colon :): `UIInterfaceOrientationPortrait`, `UIInterfaceOrientationPortraitUpsideDown`, `UIInterfaceOrientationLandscapeLeft`, `UIInterfaceOrientationLandscapeRight`. Notice that the IDE plugin has an \"Interface Orientation\" combo box you *should* use under the iOS section."); + set("{{#Ios#ios.minDeploymentTarget}}.label", "Min deployment target"); + set("{{#Ios#ios.minDeploymentTarget}}.type", "TextField"); + set("{{#Ios#ios.minDeploymentTarget}}.description", "The null and empty-string reads of this hint are presence checks; 6.0 is the substantive default (IPhoneBuilder.java:4671)."); + set("{{#Ios#ios.newStorageLocation}}.label", "New storage location"); + set("{{#Ios#ios.newStorageLocation}}.type", "Checkbox"); + set("{{#Ios#ios.newStorageLocation}}.description", "true/false defaults to false but defined on new projects as true by default. This changes the storage directory on iOS from using caches to using the documents directory which is the recommended location but might break compatibility. This is described in https://github.com/codenameone/CodenameOne/issues/1480[this issue]"); + set("{{#Ios#ios.objC}}.label", "Obj c"); + set("{{#Ios#ios.objC}}.type", "Checkbox"); + set("{{#Ios#ios.objC}}.description", "Added the `-ObjC` compile flag to the project files which some native libraries require"); + set("{{#Ios#ios.plistInject}}.label", "Plist inject"); + set("{{#Ios#ios.plistInject}}.type", "TextArea"); + set("{{#Ios#ios.plistInject}}.description", "entries to inject into the iOS plist file during build."); + set("{{#Ios#ios.pods}}.label", "Pods"); + set("{{#Ios#ios.pods}}.type", "TextArea"); + set("{{#Ios#ios.pods}}.description", "A comma separated list of https://cocoapods.org/[Cocoa Pods] that should be linked to the app to build it. For example, `AFNetworking ~> 2.6, ORStackView ~> 3.0, SwiftyJSON ~> 2.3`"); + set("{{#Ios#ios.pods.platform}}.label", "Pods platform"); + set("{{#Ios#ios.pods.platform}}.type", "TextField"); + set("{{#Ios#ios.pods.platform}}.description", "Sets the Cocoapods 'platform' for the Cocoapods. Some Cocoapods require a minimum platform level. For example, `ios.pods.platform=7.0`."); + set("{{#Ios#ios.pods.sources}}.label", "Pods sources"); + set("{{#Ios#ios.pods.sources}}.type", "TextArea"); + set("{{#Ios#ios.pods.sources}}.description", "Extra CocoaPods spec repositories to search, in addition to the default trunk."); + set("{{#Ios#ios.prerendered_icon}}.label", "Prerendered icon"); + set("{{#Ios#ios.prerendered_icon}}.type", "Checkbox"); + set("{{#Ios#ios.prerendered_icon}}.description", "true/false defaults to false. The iOS build process adapts the submitted icon for iOS conventions (adding an overlay) that might not be appropriate on some icons. Setting this to true leaves the icon unchanged (only scaled)."); + set("{{#Ios#ios.project_type}}.label", "Project type"); + set("{{#Ios#ios.project_type}}.type", "Select"); + set("{{#Ios#ios.project_type}}.values", "ios,ipad,iphone"); + set("{{#Ios#ios.project_type}}.description", "one of ios, ipad, iphone (defaults to ios). Indicates whether the resulting binary is targeted to the iphone only or ipad only. Notice that the IDE plugin has a \"Project Type\" combo box you *should* use under the iOS section."); + set("{{#Ios#ios.spm.packages}}.label", "Spm packages"); + set("{{#Ios#ios.spm.packages}}.type", "TextArea"); + set("{{#Ios#ios.spm.packages}}.description", "Swift Package Manager packages to link, one per entry, each written as identity|url|requirement."); + set("{{#Ios#ios.teamId}}.label", "Team id"); + set("{{#Ios#ios.teamId}}.type", "TextField"); + set("{{#Ios#ios.teamId}}.description", "Specifies the team ID associated with the iOS provisioning profile and certificate. Use `ios.debug.teamId` and `ios.release.teamId` to specify different team IDs for debug and release builds respectively."); + set("{{#Ios#ios.themeMode}}.label", "Theme mode"); + set("{{#Ios#ios.themeMode}}.type", "Select"); + set("{{#Ios#ios.themeMode}}.values", "auto,modern,ios7,legacy"); + set("{{#Ios#ios.themeMode}}.description", "`auto` (default), `modern`, `ios7`, `legacy`. `auto` (unset) keeps the existing iOS 7 flat theme so pre-refactor screenshot goldens and apps see no behavior change. `modern` / `liquid` opts in to the CSS-generated iOS Modern (liquid-glass) theme shipped from `native-themes/ios-modern/theme.css`. `ios7` / `flat` is the same as `auto` - pre-liquid iOS 7 flat theme; `legacy` / `iphone` loads the pre-iOS 7 iPhone theme. The `auto` -> modern flip is planned for a future release."); + set("{{#Ios#ios.uiscene}}.label", "Uiscene"); + set("{{#Ios#ios.uiscene}}.type", "Checkbox"); + set("{{#Ios#ios.uiscene}}.description", "true/false (defaults to true). Enables iOS UIScene lifecycle support. UIScene lets iOS manage one or more app UI sessions independently, improving lifecycle handling in modern iOS versions. Apple has indicated UIScene will be required starting with iOS 27, so this is now on by default; set the flag to `false` only if you need to temporarily fall back to the legacy `UIApplicationDelegate` lifecycle."); + set("{{#Ios#ios.urlScheme}}.label", "Url scheme"); + set("{{#Ios#ios.urlScheme}}.type", "TextField"); + set("{{#Ios#ios.urlScheme}}.description", "Allows intercepting a URL call using the syntax `urlPrefix`"); + + set("{{@Android}}.label", "Android"); + set("{{#Android#android.activity.launchMode}}.label", "Activity launch mode"); + set("{{#Android#android.activity.launchMode}}.type", "TextField"); + set("{{#Android#android.activity.launchMode}}.description", "Allows explicitly setting the `android:launchMode` attribute of the main activity in android. Default is \"singleTop,\" but for some applications you may need to change this behaviour. In particular, apps that are meant to open a file type will need to set this to \"singleTask.\" See https://developer.android.com/guide/topics/manifest/activity-element.html[Android docs for the activity element] for more information about the `android:launchMode` attribute."); + set("{{#Android#android.appBundle}}.label", "App bundle"); + set("{{#Android#android.appBundle}}.type", "Checkbox"); + set("{{#Android#android.appBundle}}.description", "Produces an Android App Bundle (.aab) rather than an APK. Required for new Play Store submissions."); + set("{{#Android#android.buildToolsVersion}}.label", "Build tools version"); + set("{{#Android#android.buildToolsVersion}}.type", "TextField"); + set("{{#Android#android.buildToolsVersion}}.description", "Android build-tools version. It also selects the compile SDK, so there is no separate compile-SDK hint."); + set("{{#Android#android.captureRecord}}.label", "Capture record"); + set("{{#Android#android.captureRecord}}.type", "TextField"); + set("{{#Android#android.captureRecord}}.description", "Indicates whether the `RECORD_AUDIO` permission should be requested. Can be `enabled` or any other value to disable this option"); + set("{{#Android#android.debug}}.label", "Debug"); + set("{{#Android#android.debug}}.type", "Checkbox"); + set("{{#Android#android.debug}}.description", "true/false defaults to true - indicates whether to include the debug version in the build. Defaults conditionally rather than to a fixed value: when android.release is on it defaults to false, and when release is off it defaults to true, so a build that selects neither still produces something installable (AndroidGradleBuilder.java:447-451)."); + set("{{#Android#android.disableR8}}.label", "Disable r8"); + set("{{#Android#android.disableR8}}.type", "Checkbox"); + set("{{#Android#android.disableR8}}.description", "Turns off R8, falling back to the older shrinker. Note that hardening requires R8, so this conflicts with harden.level."); + set("{{#Android#android.enableProguard}}.label", "Enable proguard"); + set("{{#Android#android.enableProguard}}.type", "Checkbox"); + set("{{#Android#android.enableProguard}}.description", "Boolean true/false defaults to true. Allows disabling the proguard obfuscation even on release builds, notice that this isn't recommended"); + set("{{#Android#android.gradleDep}}.label", "Gradle dep"); + set("{{#Android#android.gradleDep}}.type", "TextArea"); + set("{{#Android#android.gradleDep}}.description", "Gradle dependency statements to add to the app module, such as implementation 'com.example:lib:1.0'."); + set("{{#Android#android.hideStatusBar}}.label", "Hide status bar"); + set("{{#Android#android.hideStatusBar}}.type", "Checkbox"); + set("{{#Android#android.hideStatusBar}}.description", "Hides the Android status bar."); + set("{{#Android#android.installLocation}}.label", "Install location"); + set("{{#Android#android.installLocation}}.type", "Select"); + set("{{#Android#android.installLocation}}.values", "auto,internalOnly,preferExternal"); + set("{{#Android#android.installLocation}}.description", "Maps to android:installLocation manifest entry defaults to auto. Can also be set to internalOnly or preferExternal."); + set("{{#Android#android.licenseKey}}.label", "License key"); + set("{{#Android#android.licenseKey}}.type", "TextField"); + set("{{#Android#android.licenseKey}}.description", "The license key for the Android app, this is required if you use in-app purchase on Android"); + set("{{#Android#android.min_sdk_version}}.label", "Min sdk version"); + set("{{#Android#android.min_sdk_version}}.type", "TextField"); + set("{{#Android#android.min_sdk_version}}.description", "The least SDK required to run this app, the default value changes based on functionality but can be as low as 7. This corresponds to the XML attribute `android:minSdkVersion`."); + set("{{#Android#android.multidex}}.label", "Multidex"); + set("{{#Android#android.multidex}}.type", "Checkbox"); + set("{{#Android#android.multidex}}.description", "Boolean true/false defaults to false. Multidex allows Android binaries to reference more than 65536 methods. This slows builds a bit so you have it off by default but if you get a build error mentioning this limit you should turn this on."); + set("{{#Android#android.newFirebaseMessaging}}.label", "New firebase messaging"); + set("{{#Android#android.newFirebaseMessaging}}.type", "Checkbox"); + set("{{#Android#android.newFirebaseMessaging}}.description", "Uses the current Firebase Cloud Messaging integration. Requires AndroidX and Gradle 8.13 or newer."); + set("{{#Android#android.proguardKeep}}.label", "Proguard keep"); + set("{{#Android#android.proguardKeep}}.type", "TextArea"); + set("{{#Android#android.proguardKeep}}.description", "Arguments for the keep option in proguard allowing you to keep a pattern of files for example, `-keep class com.mypackage.ProblemClass { *; }`"); + set("{{#Android#android.release}}.label", "Release"); + set("{{#Android#android.release}}.type", "Checkbox"); + set("{{#Android#android.release}}.description", "true/false defaults to true - indicates whether to include the release version in the build"); + set("{{#Android#android.repositories}}.label", "Repositories"); + set("{{#Android#android.repositories}}.type", "TextArea"); + set("{{#Android#android.repositories}}.description", "Extra Gradle repositories to resolve dependencies from."); + set("{{#Android#android.targetSDKVersion}}.label", "Target sDKVersion"); + set("{{#Android#android.targetSDKVersion}}.type", "TextField"); + set("{{#Android#android.targetSDKVersion}}.description", "Indicates the Android SDK used to compile the Android build defaults to 21. Notice that not all targets will work since the source might have some limitations and not all SDK targets are installed on the build servers."); + set("{{#Android#and.themeMode}}.label", "Theme mode"); + set("{{#Android#and.themeMode}}.type", "Select"); + set("{{#Android#and.themeMode}}.values", "auto,modern,hololight,legacy"); + set("{{#Android#and.themeMode}}.description", "`auto`, `modern` / `material`, `hololight` (default for existing apps), `legacy`. `auto` and `modern` / `material` opt in to the CSS-generated Android Material 3 theme from `native-themes/android-material/theme.css`. `hololight` is Android Holo Light (what the framework shipped on API 14+ before this refactor). `legacy` loads the pre-Holo Android theme. The legacy alias `cn1.androidTheme` is still accepted, and `and.hololight=true` still maps to `hololight`. The default stays on `hololight` for existing apps until you flip in a future release."); + set("{{#Android#android.topDependency}}.label", "Top dependency"); + set("{{#Android#android.topDependency}}.type", "TextArea"); + set("{{#Android#android.topDependency}}.description", "Statements added to the top-level Gradle build file rather than the app module."); + set("{{#Android#android.useAndroidX}}.label", "Use android x"); + set("{{#Android#android.useAndroidX}}.type", "Checkbox"); + set("{{#Android#android.useAndroidX}}.description", "Use Android X instead of support libraries. This will also run a find/replace on all source files to replace support libraries and artifacts with AndroidX equivalents."); + set("{{#Android#android.xapplication}}.label", "Xapplication"); + set("{{#Android#android.xapplication}}.type", "TextArea"); + set("{{#Android#android.xapplication}}.description", "defaults to an empty string. Allows developers of native Android code to add text within the application block to define things such as widgets, services etc."); + set("{{#Android#android.xgradle}}.label", "Xgradle"); + set("{{#Android#android.xgradle}}.type", "TextArea"); + set("{{#Android#android.xgradle}}.description", "Arbitrary text spliced into the generated app-module Gradle file."); + set("{{#Android#android.xpermissions}}.label", "Xpermissions"); + set("{{#Android#android.xpermissions}}.type", "TextArea"); + set("{{#Android#android.xpermissions}}.description", "more permissions for the Android manifest"); + + set("{{@Desktop}}.label", "Desktop"); + set("{{#Desktop#desktop.adaptToRetina}}.label", "Adapt to retina"); + set("{{#Desktop#desktop.adaptToRetina}}.type", "Checkbox"); + set("{{#Desktop#desktop.adaptToRetina}}.description", "Boolean true/false defaults to true. When set to true some values will ve implicitly doubled to deal with retina displays and icons etc. Will use higher DPI's"); + set("{{#Desktop#desktop.fullscreen}}.label", "Fullscreen"); + set("{{#Desktop#desktop.fullscreen}}.type", "Checkbox"); + set("{{#Desktop#desktop.fullscreen}}.description", "Starts the desktop build in full-screen mode."); + set("{{#Desktop#desktop.height}}.label", "Height"); + set("{{#Desktop#desktop.height}}.type", "TextField"); + set("{{#Desktop#desktop.height}}.description", "Height in pixels for the form in desktop builds, will be doubled for retina grade displays. Defaults to 600."); + set("{{#Desktop#desktop.interactiveScrollbars}}.label", "Interactive scrollbars"); + set("{{#Desktop#desktop.interactiveScrollbars}}.type", "Checkbox"); + set("{{#Desktop#desktop.interactiveScrollbars}}.description", "Enables grab-able, click-to-page desktop scrollbars."); + set("{{#Desktop#desktop.resizable}}.label", "Resizable"); + set("{{#Desktop#desktop.resizable}}.type", "Checkbox"); + set("{{#Desktop#desktop.resizable}}.description", "Boolean true/false defaults to true. Indicates whether the UI in the desktop build is resizable"); + set("{{#Desktop#desktop.titleBar}}.label", "Title bar"); + set("{{#Desktop#desktop.titleBar}}.type", "Select"); + set("{{#Desktop#desktop.titleBar}}.values", "native,custom,toolbar"); + set("{{#Desktop#desktop.titleBar}}.description", "How the desktop window is framed: native for the OS title bar and menu bar, custom for an undecorated window with a Codename One drawn title bar, or toolbar for the legacy in-app Toolbar. An unrecognized value falls back to native with a warning."); + set("{{#Desktop#desktop.width}}.label", "Width"); + set("{{#Desktop#desktop.width}}.type", "TextField"); + set("{{#Desktop#desktop.width}}.description", "Width in pixels for the form in desktop builds, will be doubled for retina grade displays. Defaults to 800."); + + set("{{@OnDeviceDebug}}.label", "On-Device Debugging"); + set("{{#OnDeviceDebug#android.onDeviceDebug}}.label", "Android"); + set("{{#OnDeviceDebug#android.onDeviceDebug}}.type", "Checkbox"); + set("{{#OnDeviceDebug#android.onDeviceDebug}}.description", "Boolean true/false defaults to false. When `true`, the generated `AndroidManifest.xml` is marked `android:debuggable=\"true\"`, R8/proguard is disabled, and the build is pinned to debug-only (`android.release` is forced off and `android.debug` is forced on) so a stray hint can't ship a release-signed APK that's `debuggable=\"true\"`. Pair with the `cn1:android-on-device-debugging` Maven goal (or the bundled IntelliJ run configs) to install, launch, forward JDWP, and stream logcat through adb. Has no effect on builds that don't carry it — release builds are unaffected. See the On-Device Debugging (Android) chapter for the full flow."); + set("{{#OnDeviceDebug#ios.onDeviceDebug}}.label", "Ios"); + set("{{#OnDeviceDebug#ios.onDeviceDebug}}.type", "Checkbox"); + set("{{#OnDeviceDebug#ios.onDeviceDebug}}.description", "Boolean true/false defaults to false. When `true`, the iOS build links a small JDWP listener thread (`cn1_debugger`) into the binary and the ParparVM translator emits source-line and locals metadata so a desktop proxy can serve the running app to any JDWP-speaking debugger. Has no effect on release builds. See the On-Device Debugging (iOS) chapter for the full flow."); + set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyHost}}.label", "Ios proxy host"); + set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyHost}}.type", "TextField"); + set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyHost}}.description", "Hostname or IP address the device-side listener dials to reach the desktop proxy. Default `127.0.0.1` (correct for the native iOS simulator). For a physical device, set this to the developer laptop's LAN IP. Has no effect unless `ios.onDeviceDebug=true`."); + set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyPort}}.label", "Ios proxy port"); + set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyPort}}.type", "TextField"); + set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyPort}}.description", "TCP port on `ios.onDeviceDebug.proxyHost` where the proxy is listening for the device. Default `55333`. Has no effect unless `ios.onDeviceDebug=true`."); + set("{{#OnDeviceDebug#ios.onDeviceDebug.waitForAttach}}.label", "Ios wait for attach"); + set("{{#OnDeviceDebug#ios.onDeviceDebug.waitForAttach}}.type", "Checkbox"); + set("{{#OnDeviceDebug#ios.onDeviceDebug.waitForAttach}}.description", "Boolean true/false defaults to false. When `true`, the app blocks at startup until the proxy connects and the IDE tells the VM to continue. Useful when the breakpoint to investigate fires during app boot. Has no effect unless `ios.onDeviceDebug=true`."); + + set("{{@Build}}.label", "General"); + set("{{#Build#facebook.appId}}.label", "Facebook app id"); + set("{{#Build#facebook.appId}}.type", "TextField"); + set("{{#Build#facebook.appId}}.description", "The application ID for an app that requires native Facebook login integration, this defaults to null which means native Facebook support shouldn't be in the app"); + set("{{#Build#gcm.sender_id}}.label", "Gcm sender id"); + set("{{#Build#gcm.sender_id}}.type", "TextField"); + set("{{#Build#gcm.sender_id}}.description", "The Android/chrome push identifier, see the push section for more details"); + set("{{#Build#nativeTheme}}.label", "Native theme"); + set("{{#Build#nativeTheme}}.type", "Select"); + set("{{#Build#nativeTheme}}.values", "modern,legacy,custom"); + set("{{#Build#nativeTheme}}.description", "`modern`, `legacy`, `custom` (default unset). Cross-platform override that sets both `ios.themeMode` and `and.themeMode` together when those aren't set explicitly. `modern` = liquid glass + Material 3, `legacy` = iOS 7 flat + Holo Light, `custom` disables the framework native theme entirely. The legacy alias `cn1.nativeTheme` is still accepted."); + set("{{#Build#noExtraResources}}.label", "No extra resources"); + set("{{#Build#noExtraResources}}.type", "Checkbox"); + set("{{#Build#noExtraResources}}.description", "true/false (defaults to false). Blocks codename one from injecting its own resources when set to true, the only effect this has is in slightly reducing archive size. This might have adverse effects on some features of Codename One so it isn't recommended."); + + set("{{@Hardening}}.label", "App Hardening"); + set("{{#Hardening#harden.allowUnhardenedLocalBuild}}.label", "Allow unhardened local build"); + set("{{#Hardening#harden.allowUnhardenedLocalBuild}}.type", "Checkbox"); + set("{{#Hardening#harden.allowUnhardenedLocalBuild}}.description", "Permits a local or source build to run with hardening requested but not applied. Without it such a build is refused, so a hardened app is never shipped from a target that cannot actually harden it."); + set("{{#Hardening#harden.controlFlow}}.label", "Control flow"); + set("{{#Hardening#harden.controlFlow}}.type", "Select"); + set("{{#Hardening#harden.controlFlow}}.values", "off,on"); + set("{{#Hardening#harden.controlFlow}}.description", "Overrides control-flow obfuscation independently of harden.level."); + set("{{#Hardening#harden.keep}}.label", "Keep"); + set("{{#Hardening#harden.keep}}.type", "TextArea"); + set("{{#Hardening#harden.keep}}.description", "Keep rules in ProGuard syntax, one per line, for classes that are resolved by name at runtime and so cannot be found by the automatic analysis. Same syntax as android.proguardKeep, so existing rules port directly. Rules are separated by newlines only, because a semicolon is legal inside a rule body such as { *; }."); + set("{{#Hardening#harden.level}}.label", "Level"); + set("{{#Hardening#harden.level}}.type", "Select"); + set("{{#Hardening#harden.level}}.values", "off,standard,aggressive,paranoid"); + set("{{#Hardening#harden.level}}.description", "Master switch for app hardening: off, standard, aggressive or paranoid. An unrecognized value fails the build rather than being quietly treated as off."); + set("{{#Hardening#harden.rename}}.label", "Rename"); + set("{{#Hardening#harden.rename}}.type", "Checkbox"); + set("{{#Hardening#harden.rename}}.description", "Overrides symbol renaming independently of harden.level."); + set("{{#Hardening#harden.strings}}.label", "Strings"); + set("{{#Hardening#harden.strings}}.type", "Select"); + set("{{#Hardening#harden.strings}}.values", "off,constants,all"); + set("{{#Hardening#harden.strings}}.description", "Overrides string obfuscation independently of harden.level: off, constants or all."); + } + + /** Idempotent setter: does not overwrite user or project-level metadata. */ + private static void set(String suffix, String value) { + String key = "codename1.arg." + suffix; + if (System.getProperty(key) == null) { + System.setProperty(key, value); + } + } +} diff --git a/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintSchemaDefaults.java b/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintSchemaDefaults.java index 584e2dd75ae..1f709f35387 100644 --- a/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintSchemaDefaults.java +++ b/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintSchemaDefaults.java @@ -235,6 +235,12 @@ static void register() { + "category, android.software.leanback uses-feature, touchscreen " + "required=false) and a generated tv_banner drawable. With the " + "hint off the manifest is unchanged."); + + // Everything else that has a build hint annotation, generated from the + // catalog. Registered last on purpose: set() never overwrites, so the + // hand-written labels and descriptions above win and this only fills in + // the hints nobody has written prose for. + BuildHintCatalogDefaults.register(); } /** Idempotent setter: does not overwrite user / project-level hint metadata. */ diff --git a/Ports/JavaSE/src/com/codename1/impl/javase/Simulator.java b/Ports/JavaSE/src/com/codename1/impl/javase/Simulator.java index c89f10b3775..5fa3c829dba 100644 --- a/Ports/JavaSE/src/com/codename1/impl/javase/Simulator.java +++ b/Ports/JavaSE/src/com/codename1/impl/javase/Simulator.java @@ -160,6 +160,7 @@ public static void main(final String[] argv) throws Exception { files.add(commonClasses.getAbsoluteFile()); } loadSimulatorProperties(cn1Props.getParentFile()); + publishAnnotationBuildHints(cn1Props.getParentFile()); } if (isDebug && usingHotswapAgent) { HotswapProperties hotswapProperties = new HotswapProperties(); @@ -451,4 +452,69 @@ private List getExtraClasses() { } } + + /** + * Publishes build hints declared as annotations so the simulator sees them. + * + *

The simulator never runs {@code cn1:build}, so it never sees the build + * request the annotations feed. Without this, moving a hint like + * {@code desktop.titleBar} or {@code nativeTheme} out of + * {@code codenameone_settings.properties} and onto the main class would + * silently stop it working under {@code cn1:run} -- the build would still be + * right and only the simulator would be wrong, which is the hardest kind of + * discrepancy to track down.

+ * + *

Published as system properties rather than added as another source to + * {@code JavaSEPort.buildHint} because several readers bypass that method + * and call {@code System.getProperty("codename1.arg....")} directly. Setting + * the property fixes those, and every future one, with no change to them.

+ * + *

An existing value always wins, which is what preserves {@code -D}: the + * JVM has already applied the command line by the time this runs.

+ * + *

Read straight off disk, not through {@code getResourceAsStream}: at this + * point in {@code main} the application classes are not on any classloader + * yet -- the loader is built from {@code files} further down.

+ */ + private static void publishAnnotationBuildHints(File projectDir) { + if (projectDir == null) { + return; + } + File f = new File(projectDir, "target" + File.separator + "classes" + + File.separator + "META-INF" + File.separator + "codenameone" + + File.separator + "build-hints.properties"); + if (!f.isFile()) { + return; + } + java.util.Properties p = new java.util.Properties(); + FileInputStream in = null; + try { + in = new FileInputStream(f); + p.load(in); + } catch (IOException ex) { + System.err.println("Warning: could not read " + f + ": " + ex.getMessage()); + return; + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException ignored) { + // read-only stream; nothing useful to do + } + } + } + int applied = 0; + for (String key : p.stringPropertyNames()) { + if (!key.startsWith("codename1.arg.")) { + continue; + } + if (System.getProperty(key) == null) { + System.setProperty(key, p.getProperty(key)); + applied++; + } + } + if (applied > 0) { + System.out.println("Applied " + applied + " build hint(s) from annotations"); + } + } } diff --git a/docs/demos/common/codenameone_settings.properties b/docs/demos/common/codenameone_settings.properties index 8494fded9dd..f096134cbe8 100644 --- a/docs/demos/common/codenameone_settings.properties +++ b/docs/demos/common/codenameone_settings.properties @@ -1,7 +1,6 @@ codename1.android.keystore= codename1.android.keystoreAlias= codename1.android.keystorePassword= -codename1.arg.ios.newStorageLocation=true codename1.arg.java.version=17 codename1.displayName=DemoCode codename1.icon=icon.png diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java index 759bde784ab..6ed5a799391 100644 --- a/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java +++ b/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java @@ -1,10 +1,12 @@ package com.codenameone.developerguide; import com.codename1.system.Lifecycle; +import com.codename1.annotations.buildhints.*; /** * Application entry point that launches the demo browser. */ +@Ios(newStorageLocation = true) public class DemoCode extends Lifecycle { @Override public void runApp() { diff --git a/docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc b/docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc index 4509a700c8a..fb3dd6f1703 100644 --- a/docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc +++ b/docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc @@ -25,715 +25,19 @@ Application code can read a custom build argument through `Display.getProperty() include::../demos/common/src/main/java/com/codenameone/developerguide/advancedtopics/AppArgSnippet.java[tag=appArg,indent=0] ---- -Here is the current list of supported arguments. Build hints change over time, so consult the discussion forum if you don't find what you need here: +Here is the current list of supported arguments, generated from the same catalog +the builders and the annotations are generated from: -.Build hints -|=== -|Name |Description - -|build.cn1Version -|Pro/Enterprise only. Pins the cloud build to a specific released Codename One version using the Maven release scheme (for example `7.0.182`), or to `master` to build against the current development head. The build server fetches that version's framework artifacts. Pro accounts can target versions published within the last two months; Enterprise within the last six months. Requesting an older version, a version that was never published, or using this hint without a Pro/Enterprise subscription fails the build with an explanatory error. See <>. - -|android.debug -|true/false defaults to true - indicates whether to include the debug version in the build - -|android.release -|true/false defaults to true - indicates whether to include the release version in the build - -|android.onDeviceDebug -|Boolean true/false defaults to false. When `true`, the generated `AndroidManifest.xml` is marked `android:debuggable="true"`, R8/proguard is disabled, and the build is pinned to debug-only (`android.release` is forced off and `android.debug` is forced on) so a stray hint can't ship a release-signed APK that's `debuggable="true"`. Pair with the `cn1:android-on-device-debugging` Maven goal (or the bundled IntelliJ run configs) to install, launch, forward JDWP, and stream logcat through adb. Has no effect on builds that don't carry it — release builds are unaffected. See the <> for the full flow. - -|android.installLocation -|Maps to android:installLocation manifest entry defaults to auto. Can also be set to internalOnly or preferExternal. - -|android.xapplication -|defaults to an empty string. Allows developers of native Android code to add text within the application block to define things such as widgets, services etc. - -|android.permission.PERMISSION_NAME -|true/false Whether to include a particular permission. Use of these build hints is preferred to `android.xpermissions` since they avoid possible conflicts with libraries. See https://developer.android.com/reference/android/Manifest.permission.html[Android's `Manifest.permission` docs] for a full list of permissions. - -|android.permission.PERMISSION_NAME.maxSdkVersion -|Will be translated to the `maxSdkVersion` attribute of the `` tag for the corresponding `android.permission.PERMISSION_NAME` build hint. (Optional) - -|android.permission.PERMISSION_NAME.required -|true/false Will be translated to the `required` attribute of the `` tag for the corresponding `android.permission.PERMISSION_NAME` build hint. (Optional) - -|android.xpermissions -|more permissions for the Android manifest - -|android.xintent_filter -|Allows adding an intent filter to the main android activity - -|android.tv -|true/false (defaults to false). Marks the build as an Android TV / Google TV app. Adds the `LEANBACK_LAUNCHER` intent category to the launcher activity (so the app appears on the TV home screen), declares the `android.software.leanback` feature, makes `android.hardware.touchscreen` optional (so it installs on touchless TVs), and generates a 320×180 launcher banner (`@drawable/tv_banner`) from the app icon. The same APK still installs and runs on phones and tablets, and `CN.isTV()` returns true at runtime on a TV. - - -|android.activity.launchMode -|Allows explicitly setting the `android:launchMode` attribute of the main activity in android. Default is "singleTop," but for some applications you may need to change this behaviour. In particular, apps that are meant to open a file type will need to set this to "singleTask." See https://developer.android.com/guide/topics/manifest/activity-element.html[Android docs for the activity element] for more information about the `android:launchMode` attribute. - - -|android.licenseKey -|The license key for the Android app, this is required if you use in-app purchase on Android - -|android.signingV1 -|true/false Default true. See https://source.android.com/docs/security/features/apksigning - -|android.signingV2 -|true/false Default true. See https://source.android.com/docs/security/features/apksigning - -|android.signingV3 -|true/false Default true. See https://source.android.com/docs/security/features/apksigning - -|android.signingV4 -|true/false Default true. See https://source.android.com/docs/security/features/apksigning - -|android.stack_size -|Size in bytes for the Android stack thread - -|android.statusbar_hidden -|true/false defaults to false. When set to true hides the status bar on Android devices. - -|android.facebook_permissions -|Permissions for Facebook used in the Android build target, applicable only if Facebook native integration is used. - -|android.googleAdUnitId -|Allows integrating admob/google play ads, this is effectively identical to google.adUnitId but only applies to Android - -|android.googleAdUnitTestDevice -|Device key used to mark a specific Android device as a test device for Google Play ads defaults to C6783E2486F0931D9D09FABC65094FDF - -|android.includeGPlayServices -|*Deprecated, please android.playService.+++*+++!* Indicates whether Google Play Services should be included into the build, defaults to false but that might change based on the functionality of the application and other build hints. Adding Google Play Services support allows you to use a more refined location implementation and invoke some Google specific functionality from native code. - -|android.playService.plus, android.playService.auth, android.playService.base, android.playService.identity, android.playService.indexing, android.playService.appInvite, android.playService.analytics, android.playService.cast, android.playService.gcm, android.playService.drive, android.playService.fitness, android.playService.location, android.playService.maps, android.playService.ads, android.playService.vision, android.playService.nearby, android.playService.panorama, android.playService.games, android.playService.safetynet, android.playService.wallet, android.playService.wearable -|Allows including only a specific play services library portion. Notice that this setting conflicts with the deprecated `android.includeGPlayServices` and only works with the Gradle-based Android build pipeline. + - -If none of the services are defined to true then plus, auth, base, analytics, gcm, location, maps & ads will be set to true. If one or more of the `android.playService` entries are defined to something then all entries will default to false. - -|android.playServicesVersion -| The version number of play services to build against. Experimental. **Use with caution** as building against versions other than the server default may introduce incompatibilities with some Codename One APIs. - -|xxx.minPlayServicesVersion -|This is a special case build hint. You can use any prefix to the build hint and the convention is to use your cn1lib name. It's identical to `android.minPlayServicesVersion` with the exception that the "highest version wins." That way if your cn1lib requires play services 9+ and uses: `myLib.minPlayServicesVersion=9.0.0` and another library has `otherLib.minPlayServicesVersion=10.0.0` then play services will be 10.0.0 - -|android.multidex -|Boolean true/false defaults to false. Multidex allows Android binaries to reference more than 65536 methods. This slows builds a bit so you have it off by default but if you get a build error mentioning this limit you should turn this on. - -|android.headphoneCallback -|Boolean true/false defaults to false. When set to true it assumes the main class has two methods: `headphonesConnected` & `headphonesDisconnected` which it invokes appropriately as needed - -|android.gpsPermission -|Indicates whether the GPS permission should be requested, it's autodetected by default if you use the location API. But, some code might want to explicitly define it - -|android.asyncPaint -|Boolean true/false defaults to true. Toggles the Android pipeline between the legacy pipeline (false) and new pipeline (true) - -|android.stringsXml -|Allows injecting more entries into the strings.xml file using a value that includes something like this `value1value2` - -|android.supportV4 -|Boolean true/false defaults to false but that can change based on usage (for example, push implicitly activates this). Indicates whether the android support v4 library should be included in the build - -|android.style -|Allows injecting more data into the `styles.xml` file right before the closing resources tag - -|android.enableAdaptiveIcons -|Boolean true/false defaults to false. Enables Android adaptive icon generation in Android Gradle builds. When enabled, Codename One generates `mipmap` launcher resources (`ic_launcher`, `ic_launcher_foreground`, and adaptive XML in `mipmap-anydpi-v26`) and uses them in the application manifest (`android:icon` and `android:roundIcon`). - -|android.adaptiveIconBackground -|Background color to use for adaptive icons when `android.enableAdaptiveIcons=true` and no background image is supplied. Defaults to `#ffffff` and is written as `@color/ic_launcher_background`. - -|android.adaptiveIconBackgroundImage -|Optional path (relative to the root of the native Android project) to an image file to use as the adaptive icon background when `android.enableAdaptiveIcons=true`. If this property is set, it overrides `android.adaptiveIconBackground`. - -|android.cusom_layout1 -|Applies to any number of layouts as long as they're in sequence (for example, android.cusom_layout2, android.cusom_layout3 etc.). Will write the content of the argument as a layout XML file and give it the name `cusom_layout1.xml` onwards. This can be used by native code to work with XML files - -|android.keyboardOpen -|Boolean true/false defaults to true. Toggles the new async keyboard mode that leaves the keyboard open while you move between text components - -|android.versionCode -|Allows overriding the auto generated version number with a custom internal version number specifically used for the XML attribute `android:versionCode` - -|android.captureRecord -|Indicates whether the `RECORD_AUDIO` permission should be requested. Can be `enabled` or any other value to disable this option - -|android.nonconsumable -|Comma delimited string of items that are non-consumable in the in-app purchase API - -|android.removeBasePermissions -|Boolean true/false defaults to false. Disables the built-in permissions specifically `INTERNET` permission (that is, no networking...) - -|android.blockExternalStoragePermission -|Boolean true/false defaults to false. Disables the external storage (SD card) permission - -|android.blockReadMediaPermissions -|Boolean true/false, defaults to the value of `android.blockExternalStoragePermission`. Suppresses the `READ_MEDIA_VIDEO` and `READ_MEDIA_AUDIO` permissions that playing a URI adds on API 33 and above - -|android.requestReadMediaPermissions -|Boolean true/false defaults to false. Declares `READ_MEDIA_IMAGES`, `READ_MEDIA_VIDEO` and `READ_MEDIA_AUDIO` on API 33 and above even when the build detected no media playback. `READ_MEDIA_IMAGES` is only ever added by this hint - -|android.min_sdk_version -|The least SDK required to run this app, the default value changes based on functionality but can be as low as 7. This corresponds to the XML attribute `android:minSdkVersion`. - -|android.manifest.queries -|Embeds XML content into the section of the Android manifest file. This is https://developer.android.com/training/package-visibility[required in Android 11 for package visibility]. See https://developer.android.com/guide/topics/manifest/queries-element[queries element Android documentation]. - -|android.mockLocation -|Boolean true/false defaults to true. Toggles the mock location permission which is on by default, this allows easier debugging of Android device location based services - -|android.smallScreens -|Boolean true/false defaults to true. Corresponds to the `android:smallScreens` XML attribute and allows disabling the support for small phones - -|android.xapplication_attr -|Allows injecting more attributes into the `application`` tag in the Android XML - -|android.xactivity -|Allows injecting more attributes into the `activity` tag in the Android XML - -|android.streamMode -|The mode in which the volume key should behave, defaults to OS default. Allows setting it to `music` for music playback apps - -|android.pushVibratePattern -|Comma delimited long values to describe the push pattern of vibrate used for the `setVibrate` native method - -|android.enableProguard -|Boolean true/false defaults to true. Allows disabling the proguard obfuscation even on release builds, notice that this isn't recommended - -|android.proguardKeep -|Arguments for the keep option in proguard allowing you to keep a pattern of files for example, `-keep class com.mypackage.ProblemClass { *; }` - -|android.shrinkResources -|Boolean true/false defaults to false. Used only in conjunction with android.enableProguard. Strips out unused resources to reduce apk size. Since 7.0 - -|android.sharedUserId -|Allows adding a manifest attribute for the sharedUserId option - -|android.sharedUserLabel -|Allows adding a manifest attribute for the sharedUserLabel option - -|android.targetSDKVersion -|Indicates the Android SDK used to compile the Android build defaults to 21. Notice that not all targets will work since the source might have some limitations and not all SDK targets are installed on the build servers. - -|android.useAndroidX -|Use Android X instead of support libraries. This will also run a find/replace on all source files to replace support libraries and artifacts with AndroidX equivalents. - -|android.rootCheck -|Boolean true/false defaults to false. Indicates whether the app should check for root access on the device. If root access is detected, the app will exit. - -|android.tapjackingGuard -|Boolean true/false defaults to false. Switches on tapjacking / screen-overlay protection at launch, so touches that arrive while another app's window covers this one are detected and dropped. See the security chapter. - -|android.tapjackingGuard.mode -|`block` (default), `strict`, `report` or `off`. `block` drops gestures that start on a fully obscured window, `report` only observes, `strict` also drops touches where only part of the window is covered (which benign system UI can trigger). Only relevant if `android.tapjackingGuard=true`. - -|android.tapjackingGuard.hideOverlays -|Boolean true/false defaults to true. Also asks Android 12+ to hide overlay windows drawn over the app, which is the only mitigation that covers native peer components, and declares the `HIDE_OVERLAY_WINDOWS` permission it requires. Only relevant if `android.tapjackingGuard=true`. - -|android.hideOverlayWindows -|Boolean true/false defaults to false. Declares the `android.permission.HIDE_OVERLAY_WINDOWS` permission needed by `DeviceIntegrity.setHideOverlayWindows()` on Android 12+, for apps that call the runtime API without enabling `android.tapjackingGuard`. A normal install-time permission, so the user sees no prompt. - -|android.fridaDetection -|Boolean true/false defaults to false. Indicates whether the app should check for the presence of the https://www.frida.re/[Frida] dynamic instrumentation toolkit on the device. If Frida is detected, the app will exit. This uses the [frida-blocker](https://github.com/shannah/frida-blocker) library to perform the frida detection. - -|android.fridaVersion -|x.y.z The version of [frida-blocker](https://github.com/shannah/frida-blocker) to use to perform frida detection. This is only relevant if `android.fridaDetection=true`. If omitted, it will use the latest tested version in the build server. - -|android.fridaDebugLogging -|Boolean true/false defaults to false. If true, it will add verbose debug logs during frida detection to show which check if fails on. - -|android.theme -|Light or Dark defaults to Light. On Android 4+ the default Holo theme is used to render the native widgets sometimes and this indicates whether holo light or holo dark is used. This doesn't affect the Codename One theme but that might change in the future. - -|android.web_loading_hidden -|true/false defaults to false - set to true to hide the progress indicator that appears when loading a web page on Android. - -|block_server_registration -|true/false flag defaults to false. By default Codename One applications register with the Codename One server. Setting this to true blocks them from sending information to the Codename One cloud, which is kept for statistical purposes and may be used to provide more installation stats in the future. - -|facebook.appId -|The application ID for an app that requires native Facebook login integration, this defaults to null which means native Facebook support shouldn't be in the app - -|facebook.clientToken -|The client token for an app that requires native Facebook login integration, this is required if the facebook.appId is set. - -|gcm.sender_id -|The Android/chrome push identifier, see the push section for more details - -| android.background_push_handling -| Deliver push messages on Android when the app is minimized by setting this to "true." Default behaviour is to deliver the message only if the app is in the foreground when received, or after the user taps on the notification to open the app, if the app was in the background when the message was received. - -| desktop.mac.plist.PLISTKEY -| Set the key `PLISTKEY` in the Info.plist file for desktop mac build. For example, `desktop.mac.plist.LSApplicationCategoryType=public.app-category.business`. See https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Introduction/Introduction.html[Apple Documentation of Info.plist keys and values for a full list of supported keys]. -+ -Only supported for App Store builds. See https://www.codenameone.com/developer-guide.html#_mac_os_desktop_build_options[macOS Desktop Build Options] for more information. - -| desktop.mac.plistInject -| Injects raw XML into the Info.plist file for desktop builds. For example, `desktop.mac.plistInject=LSApplicationCategoryTypepublic.app-category.business` -+ -Only supported for App Store builds. See https://www.codenameone.com/developer-guide.html#_mac_os_desktop_build_options[macOS Desktop Build Options] for more information. - -| windows.arch -| Native Windows (`windows-device`) target CPU: `x64` (default), `arm64`, or `both`. An x64 binary also runs on Windows-on-ARM via the OS's x64 emulation. See <>. - -| windows.debug -| Native Windows target: `true`/`false` (default `false`). When `false` the `.exe` is optimized and stripped (with the `.pdb` in its own file); `true` keeps symbols (a single x64 build) for crash symbolication. Optimizations stay on either way. - -| windows.signing.pkcs12 / windows.signing.password / windows.signing.timestampUrl / windows.signing.digest / windows.signing.name / windows.signing.url -| Native Windows Authenticode signing of the produced `.exe` (via `osslsigncode`). A certificate is taken from `windows.signing.pkcs12` or the build's uploaded certificate; set `windows.signing=false` to skip. Unsigned binaries run but trip SmartScreen / "Unknown publisher." - -| linux.arch -| Native Linux (`linux-device`) target CPU: `x64` (default), `arm64`, or `both`. See <>. - -| linux.debug -| Native Linux target: `true`/`false` (default `false`). When `false` the ELF is optimized and stripped (debug info is split into a separate `.debug`); `true` keeps symbols (`RelWithDebInfo`) for crash symbolication. Optimizations stay on either way. - -| linux.libc -| Native Linux target: `glibc` (default) or `musl`. The default compiles against an old glibc so the ELF runs on essentially any mainstream distro; `musl` targets Alpine (where the GTK stack is itself musl-built). A glibc binary and a musl binary aren't interchangeable. - -|ios.associatedDomains -|Comma-delimited list of domains associated with this app. Each domain should be prefixed by a supported prefix. For example, "applinks:" or "webcredentials:." See https://developer.apple.com/documentation/security/password_autofill/setting_up_an_app_s_associated_domains?language=objc[Apple's documentation on Associated domains] for more information. - -|ios.bitcode -|true/false defaults to false. Enables bitcode support for the build. - -|ios.debug.archs -|Can be set to "armv7" to force iOS debug builds to be 32 bit. By default, debug builds are 64 bit only. - -|ios.release.archs -|Can be set to "arm64" to only build iOS release builds for 64 bit. By default, release builds are both 32 and 64 bit. - -|ios.distributionMethod -|Specifies distribution type for debug iOS builds. This is used for enterprise or ad-hoc builds (using values "enterprise" and "ad-hoc" respectively). - -|ios.debug.distributionMethod -|Specifies distribution type for debug iOS builds only. This is used for enterprise or ad-hoc builds (using values "enterprise" and "ad-hoc" respectively). - -|ios.release.distributionMethod -|Specifies distribution type for release iOS builds only. This is used for enterprise or ad-hoc builds (using values "enterprise" and "ad-hoc" respectively). - -|ios.keyboardOpen -|Flips between iOS keyboard open mode and autofold keyboard mode. Defaults to true which means the keyboard will remain open and not fold automatically when editing moves to another field. - -|ios.uiscene -|true/false (defaults to true). Enables iOS UIScene lifecycle support. UIScene lets iOS manage one or more app UI sessions independently, improving lifecycle handling in modern iOS versions. Apple has indicated UIScene will be required starting with iOS 27, so this is now on by default; set the flag to `false` only if you need to temporarily fall back to the legacy `UIApplicationDelegate` lifecycle. - -|ios.urlScheme -|Allows intercepting a URL call using the syntax `urlPrefix` - -|ios.useAVKit -|Use AVKit for video components on iOS rather than `MPMoviePlayerController` on iOS versions 8 through 12. iOS 13 will always use AVKit, and iOS 7 and lower will always use `MPMoviePlayerController`. Default value `false` - -|ios.teamId -|Specifies the team ID associated with the iOS provisioning profile and certificate. Use `ios.debug.teamId` and `ios.release.teamId` to specify different team IDs for debug and release builds respectively. - -|ios.debug.teamId -|Specifies the team ID associated with the iOS debug provisioning profile and certificate. - -|ios.release.teamId -|Specifies the team ID associated with the iOS release provisioning profile and certificate. - -|ios.project_type -|one of ios, ipad, iphone (defaults to ios). Indicates whether the resulting binary is targeted to the iphone only or ipad only. Notice that the IDE plugin has a "Project Type" combo box you *should* use under the iOS section. - -|ios.rpmalloc -// vale-skip: write-good.TooWordy — 'minimum' refers to the deployment-target floor; 'least' would change the meaning. -|`true`/`false` Use https://github.com/rampantpixels/rpmalloc[rpmalloc] instead of malloc/free for memory allocation in ParparVM. This will cause the deployment target to be changed to a minimum of iOS 8.0. - -|ios.statusbar_hidden -|true/false defaults to false. Hides the iOS status bar if set to true. - -|ios.newStorageLocation -|true/false defaults to false but defined on new projects as true by default. This changes the storage directory on iOS from using caches to using the documents directory which is the recommended location but might break compatibility. This is described in https://github.com/codenameone/CodenameOne/issues/1480[this issue] - -|ios.prerendered_icon -|true/false defaults to false. The iOS build process adapts the submitted icon for iOS conventions (adding an overlay) that might not be appropriate on some icons. Setting this to true leaves the icon unchanged (only scaled). - -|ios.app_groups -|Space-delimited list of app groups that this app belongs to as described in https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW19[Apple's documentation]. These are added to the entitlements file with key `com.apple.security.application-groups`. - -|ios.keychainAccessGroup -|Space-delimited list of keychain access groups that this app has access to as described in https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html#//apple_ref/doc/uid/TP30000897-CH204-SW11[Apple's documentation]. These are added to the entitlements file with the key `keychain-access-groups`. - -|ios.application_exits -|true/false (defaults to false). Indicates whether the application should exit on home button press. The default is to exit, leaving the application running is only tested at the moment. - -|ios.blockScreenshotsOnEnterBackground -|true/false (defaults to false). Indicates that app should prevent iOS from taking screenshots when app enters background. Described https://shannah.github.io/cn1-recipes/#_hiding_sensitive_data_when_entering_background[here]. - -|ios.detectJailbreak -|true/false (defaults to false). When true, the iOS app will exit on launch if it detects that it's running on a jailbroken device. - -|ios.notificationPermissionAtLaunch -|true/false (defaults to false). Backward-compatibility flag for the pre-issue-#4876 behavior. By default, the iOS notification permission prompt is deferred until the app calls `Push.register()` or schedules a `LocalNotification`, matching the Android flow and giving the developer a chance to display a rationale screen first. Set this hint to `true` to restore the legacy behavior in which the prompt fires automatically inside `application:didFinishLaunchingWithOptions:` as soon as the app launches. Existing apps relying on the prompt being shown at launch should set this to `true`; new apps should leave it disabled and trigger the prompt explicitly when they're ready to ask for permission. - -|ios.applicationQueriesSchemes -|Comma separated list of url schemes that `canExecute` will respect on iOS. If the url scheme isn't mentioned here `canExecute` will return false starting with iOS 9. Notice that this collides with `ios.plistInject` when used with the `LSApplicationQueriesSchemes...` value so you should use one or the other. For example, to enable `canExecute` for a url like `myurl://xys` you can use: `myurl,myotherurl` - -|ios.themeMode -|`auto` (default), `modern`, `ios7`, `legacy`. `auto` (unset) keeps the existing iOS 7 flat theme so pre-refactor screenshot goldens and apps see no behavior change. `modern` / `liquid` opts in to the CSS-generated iOS Modern (liquid-glass) theme shipped from `native-themes/ios-modern/theme.css`. `ios7` / `flat` is the same as `auto` - pre-liquid iOS 7 flat theme; `legacy` / `iphone` loads the pre-iOS 7 iPhone theme. The `auto` -> modern flip is planned for a future release. - -|and.themeMode -|`auto`, `modern` / `material`, `hololight` (default for existing apps), `legacy`. `auto` and `modern` / `material` opt in to the CSS-generated Android Material 3 theme from `native-themes/android-material/theme.css`. `hololight` is Android Holo Light (what the framework shipped on API 14+ before this refactor). `legacy` loads the pre-Holo Android theme. The legacy alias `cn1.androidTheme` is still accepted, and `and.hololight=true` still maps to `hololight`. The default stays on `hololight` for existing apps until you flip in a future release. - -|nativeTheme -|`modern`, `legacy`, `custom` (default unset). Cross-platform override that sets both `ios.themeMode` and `and.themeMode` together when those aren't set explicitly. `modern` = liquid glass + Material 3, `legacy` = iOS 7 flat + Holo Light, `custom` disables the framework native theme entirely. The legacy alias `cn1.nativeTheme` is still accepted. +Most of the commonly used hints also have a compiler-checked form: an annotation +in `com.codename1.annotations.buildhints` that you put on the application's main +class. Written that way a misspelled name is an unknown symbol and an +unsupported value is an unknown enum constant, instead of a properties line that +is accepted, never read, and silently does nothing. The Annotation column below +names that form where one exists. Setting the same hint both ways fails the +build. -|ios.interface_orientation -|UIInterfaceOrientationPortrait by default. Indicates the orientation, one or more of (separated by colon :): `UIInterfaceOrientationPortrait`, `UIInterfaceOrientationPortraitUpsideDown`, `UIInterfaceOrientationLandscapeLeft`, `UIInterfaceOrientationLandscapeRight`. Notice that the IDE plugin has an "Interface Orientation" combo box you *should* use under the iOS section. - -|ios.xcode_version -|The version of Xcode used on the server. Defaults to 4.5; accepts 5.0 as an option and nothing else. - -|ios.multitasking -|Set to true to enable iOS multitasking and split-screen support. This only works if `ios.xcode_verson=9.2`. - -|java.version -|Valid values include 5 or 8. Indicates the JVM version that should be used for server compilation, this is defined by default for newly created apps based on the Java 8 mode selection - -|javascript.inject_proxy -|true/false (defaults to `true`). The ParparVM builder generates a same-origin proxy bundle and configures the app to use it. Setting this to `false` disables both proxy generation and proxy URL injection. - -|javascript.inject.beforeHead -| Content to be injected into the index.html file at the beginning of the `` tag. - -|javascript.inject.afterHead -| Content to be injected into the index.html file at the end of the `` tag. - -|javascript.minifying -|true/false (defaults to `true`). By default the JavaScript code is minified to reduce file size. You may optionally disable minification by setting `javascript.minifying` to `false`. - -|javascript.port -|`parparvm` (default) or `teavm`. Selects the public JavaScript compiler for cloud builds. `teavm` retains the original builder as a compatibility fallback. - -|javascript.proxy.allowedTargets -|Comma-separated target origins, host names, or wildcard subdomains that a generated proxy may access, for example `https://api.example.com,*.services.example.org`. If omitted, the proxy accepts any HTTP or HTTPS target and the build emits a warning. - -|javascript.proxy.target -|The generated ParparVM proxy deployment platform. Supported values are `jakarta-servlet` (default), `javax-servlet`, `node`, `php`, `aws-lambda`, `google-cloud-functions`, `cloudflare-workers`, and `none`. - -|javascript.proxy.url -|The URL of an existing proxy to use for network requests. Setting it suppresses generated proxy packaging unless `javascript.proxy.target` is also set. If `javascript.inject_proxy` is `false`, this build hint is ignored. - -|javascript.sourceFilesCopied -|true/false (defaults to `false`). Setting this flag to `true` will cause available java source files to be included in the resulting .zip and .war files. These may be used by Chrome during debugging. - -|javascript.stopOnErrors -|true/false (defaults to `true`). Causes a TeaVM JavaScript build to fail when the compiler reports warnings. Setting this to `false` may allow the fallback builder to complete, but can turn compiler diagnostics into runtime failures that are more difficult to debug. - -|javascript.teavm.version -| (Optional) The version of TeaVM to use for the build. *Use caution*, only use this property if you know what you're doing! - - -|google.adUnitId -|Allows integrating Admob/Google Play ads into the application see link:https://www.codenameone.com/blog/adding-google-play-ads.html[this] - -|ios.entitlementsInject -|Content to inject into the iOS entitlements file. This should be in the Plist XML format. See https://developer.apple.com/documentation/bundleresources/entitlements?language=objc[Apple Entitlements Documentation]. - -|ios.plistInject -|entries to inject into the iOS plist file during build. - -|ios.includePush -|true/false (defaults to false). Whether to include the push capabilities in the iOS build. Notice that the IDE plugin has an "Include Push" check box you *should* use under the iOS section. - -|ios.newPipeline -|Boolean true/false defaults to true. Allows toggling the OpenGL ES 2.0 drawing pipeline off to the older OGL ES 1.0 pipeline. - -|ios.headphoneCallback -|Boolean true/false defaults to false. When set to true it assumes the main class has two methods: `headphonesConnected` & `headphonesDisconnected` which it invokes appropriately as needed - -|ios.facebook_permissions -|Permissions for Facebook used in the Android build target, applicable only if Facebook native integration is used. - -|ios.applicationDidEnterBackground -|Objective-C code that can be injected into the iOS callback method (message) `applicationDidEnterBackground`. - -|ios.enableAutoplayVideo -|Boolean true/false defaults to false. Makes videos "autoplay" when loaded on iOS - -|ios.googleAdUnitId -|Allows integrating admob/google play ads, this is effectively identical to google.adUnitId but only applies to iOS - -|ios.viewDidLoad -|Objective-C code that can be injected into the iOS callback method (message) `viewDidLoad` - -|ios.googleAdUnitIdPadding -|Indicates the amount of padding to pass to the Google Ads placed at the bottom of the screen with `google.adUnitId` - -|ios.enableBadgeClear -|Boolean true/false defaults to true. Clears the badge value with every load of the app, this is useful if the app doesn't manually keep track of number values for the badge - -|ios.glAppDelegateHeader -|Objective-C code that can be injected into the iOS app delegate at the top of the file. For example, if you need to include headers or make special imports for other injected code - -|ios.glAppDelegateBody -|Objective-C code that can be injected into the iOS app delegate within the body of the file before the end. This only makes sence for methods that aren't already declared in the class - -|ios.beforeFinishLaunching -|Objective-C code that can be injected into the iOS app delegate at the top of the body of the didFinishLaunchingWithOptions callback method - -|ios.afterFinishLaunching -|Objective-C code that can be injected into the iOS app delegate at the bottom of the body of the didFinishLaunchingWithOptions callback method - -|ios.locationUsageDescription -|This flag is required for iOS 8 and newer if you're using the location API. It needs to include a description of the reason for which you need access to the users location - -|ios.NSXXXUsageDescription -|iOS privacy flags for using certain APIs. Starting with Xcode 8, you're required to add usage description strings for certain APIs. Find a full list of the available keys in https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html[Apple's docs]. Some relevant ones include `ios.NSCameraUsageDescription`, `ios.NSContactsUsageDescription`, `ios.NSLocationAlwaysUsageDescription`, `NSLocationUsageDescription`, `ios.NSMicrophoneUsageDescription`, `ios.NSPhotoLibraryAddUsageDescription`, `ios.NSSpeechRecognitionUsageDescription`, `ios.NSSiriUsageDescription` - -|ios.add_libs -|A semicolon separated list of libraries that should be linked to the app to build it - -|ios.pods -|A comma separated list of https://cocoapods.org/[Cocoa Pods] that should be linked to the app to build it. For example, `AFNetworking ~> 2.6, ORStackView ~> 3.0, SwiftyJSON ~> 2.3` - -|ios.pods.platform -// vale-skip: write-good.TooWordy — 'minimum platform level' is the standard CocoaPods term; 'least platform level' is wrong. -| Sets the Cocoapods 'platform' for the Cocoapods. Some Cocoapods require a minimum platform level. For example, `ios.pods.platform=7.0`. - -| ios.deployment_target -// vale-skip: write-good.TooWordy — 'minimum version' is the standard term for a deployment-target floor. -| Sets the deployment target for iOS builds. This is the minimum version of iOS required by a device to install the app. For example, `ios.deployment_target=8.0`. Default is '6.0'. Note: This build hint interacts with the `ios.rpmalloc` build hint. If `ios.deployment_target` is 8.0 or higher, ParparVM will use https://github.com/rampantpixels/rpmalloc[rpmalloc] by default. You can disable this default and revert back to using malloc/free by setting the `ios.rpmalloc=false` build hint. - -|ios.bundleVersion -|Indicates the version number of the bundle, this is useful if you want to create a minor version number change for the beta testing support - -|ios.objC -|Added the `-ObjC` compile flag to the project files which some native libraries require - -|ios.testFlight -|Boolean true/false defaults to false and works only for pro accounts. Enables the testflight support in the release binaries for easy beta testing. Notice that the IDE plugin has a "Test Flight" check box you *should* use under the iOS section. - -|ios.metal -|Boolean true/false defaults to true. Selects the Metal rendering backend (`CAMetalLayer`) over the legacy OpenGL ES 2 path (`CAEAGLLayer`). Metal is the supported iOS graphics API; OpenGL ES is deprecated. Set to `false` to opt out if you hit a Metal-only rendering regression. See link:#_metal_renderer[Working with iOS / Metal renderer] for details. - -|ios.metal.colorSpace -|Selects the `CAMetalLayer.colorspace` for the Metal renderer. Accepts `sRGB` (default), `displayP3`, `deviceRGB`, `linearSRGB`, `extendedSRGB`, `extendedLinearSRGB`, or `none`. Has no effect when `ios.metal=false`. See link:#_choosing_a_color_space_for_the_metal_renderer[Working with iOS / Choosing a color space] for the full table. - -|ios.generateSplashScreens -|Boolean true/false defaults to false. Enables legacy generation of splash screen images instead of the current launch storyboards. - -|ios.onDeviceDebug -|Boolean true/false defaults to false. When `true`, the iOS build links a small JDWP listener thread (`cn1_debugger`) into the binary and the ParparVM translator emits source-line and locals metadata so a desktop proxy can serve the running app to any JDWP-speaking debugger. Has no effect on release builds. See the <> for the full flow. - -|ios.onDeviceDebug.proxyHost -|Hostname or IP address the device-side listener dials to reach the desktop proxy. Default `127.0.0.1` (correct for the native iOS simulator). For a physical device, set this to the developer laptop's LAN IP. Has no effect unless `ios.onDeviceDebug=true`. - -|ios.onDeviceDebug.proxyPort -|TCP port on `ios.onDeviceDebug.proxyHost` where the proxy is listening for the device. Default `55333`. Has no effect unless `ios.onDeviceDebug=true`. - -|ios.onDeviceDebug.waitForAttach -|Boolean true/false defaults to false. When `true`, the app blocks at startup until the proxy connects and the IDE tells the VM to continue. Useful when the breakpoint to investigate fires during app boot. Has no effect unless `ios.onDeviceDebug=true`. - -|ios.wallet.extension -|Boolean true/false defaults to false. Generates an Apple Wallet issuer provisioning extension (the "From apps on your iPhone" flow in the Wallet app) and embeds it in the build. Requires `ios.wallet.appGroup` and `ios.wallet.issuerEndpoint`. See the <>. - -|ios.wallet.appGroup -|App Group id starting with `group.` shared by the app and the generated Wallet extensions. The app publishes pass entries into this group through `com.codename1.payment.WalletExtension` and the group is added to the app and extension entitlements automatically. Required when `ios.wallet.extension=true`. - -|ios.wallet.issuerEndpoint -|HTTPS URL of the issuer backend endpoint that produces the encrypted provisioning payload. The generated extension POSTs Apple's certificates/nonce plus the card identifier and auth token there as JSON. Required when `ios.wallet.extension=true`. - -|ios.wallet.includeUI -|Boolean true/false defaults to false. Also generates the Wallet authorization UI extension - a login form shown inside the Wallet app when the app reports that authentication is required. Requires `ios.wallet.authEndpoint`. - -|ios.wallet.authEndpoint -|HTTPS URL the generated login UI extension POSTs `{"username","password"}` to; the JSON response's `token` is stored in the App Group for the provisioning request. Required when `ios.wallet.includeUI=true`. - -|ios.wallet.nonuiExtensionName / ios.wallet.uiExtensionName -|Names of the generated extension targets, also used as the bundle id suffix (`.`). Default `WalletNonUIExtension` / `WalletUIExtension`. The matching App IDs must be registered with the payment-pass-provisioning entitlement and listed by the card network. - -|ios.wallet.nonuiProvisioningProfile / ios.wallet.uiProvisioningProfile -|Cloud device builds only. File name of the extension's `.mobileprovision` placed under `common/src/main/resources`. The profile must match the app's distribution certificate and carry the `com.apple.developer.payment-pass-provisioning` entitlement; the build keeps it out of the app bundle. - -|ios.wallet.nonuiProvisioningURL / ios.wallet.uiProvisioningURL -|Cloud device builds only. URL fallback for the extension provisioning profile when it isn't bundled in resources, mirroring `ios.notificationServiceExtensionProvisioningURL`. - -|ios.wallet.nonui.buildSettings.SETTING / ios.wallet.ui.buildSettings.SETTING -|Extra Xcode build settings applied to the generated extension targets, for example `ios.wallet.nonui.buildSettings.DEVELOPMENT_TEAM=ABCD123456`. Applied last so they override the generated defaults. - -|ios.wallet.nonuiImportsInject, ios.wallet.statusInject, ios.wallet.passEntriesInject, ios.wallet.remotePassEntriesInject, ios.wallet.generateRequestInject, ios.wallet.generateResponseInject, ios.wallet.uiImportsInject, ios.wallet.uiViewDidLoadInject, ios.wallet.uiAuthRequestInject, ios.wallet.uiAuthResponseInject -|Objective-C code injected at the matching marker comment in the generated Wallet extension sources, for custom behavior at each callback (for example adding fields to the issuer endpoint payload in `generateRequestInject`). See the <>. - -|ios.appext.NAME.provisioningURL -|Cloud device builds only. URL of the provisioning profile for a generic app extension dropped into `ios/app_extensions/NAME/` (or a generated extension such as `CN1Widgets`), used when the extension folder doesn't bundle a `.mobileprovision` itself. The profile is installed on the build machine and added to the export options per bundle id. Used for both debug and release builds unless a qualified variant (below) is set. An extension is signed against its own App ID, so a device build with no profile for it -- by any of the three carriers -- is refused unless the app's own profile is a wildcard that covers the extension's bundle id. - -|ios.debug.appext.NAME.provisioningURL / ios.release.appext.NAME.provisioningURL -|Cloud device builds only. Build-type-specific variants of `ios.appext.NAME.provisioningURL`: point the `debug` variant at the extension's development profile and the `release` variant at its distribution profile. The Maven build resolves the variant matching the build target (`ios-device` and `ios-on-device-debug` are debug, `ios-device-release` is release) into the unqualified hint before submitting the build; the unqualified hint acts as the fallback. The same qualifiers work for the local-path settings `codename1.ios.debug.appext.NAME.provision` / `codename1.ios.release.appext.NAME.provision`. - -|codename1.mac.appid -|Mac Native cloud builds only. The Mac bundle identifier registered in App Store Connect / Apple Developer. Distinct from `codename1.ios.appid` because Apple treats the iOS and Mac App Store records as separate products. Required for cloud Mac builds. - -|codename1.mac.certificate -|Mac Native cloud builds only. Path to the `.p12` file containing the Mac signing certificate(s) — _Mac App Distribution_ (3rd Party Mac Developer Application) for App Store builds, _Developer ID Application_ for Developer ID builds, or both bundled into the same P12 when `macNative.distribution=both`. Not interchangeable with the iOS distribution certificate. Required for cloud Mac builds. - -|codename1.mac.certificatePassword -|Mac Native cloud builds only. Password to unlock the P12 referenced by `codename1.mac.certificate`. Required for cloud Mac builds. - -|codename1.mac.provision -|Mac Native cloud builds only. Path to the Mac provisioning profile (`.provisionprofile`). Apple issues distinct provisioning profiles for Mac App Store and Developer ID distribution — pass the one that matches the chosen channel. - -|macNative.distribution -|Mac Native builds only. `appStore` (default), `developerID`, or `both`. Selects which entitlements + ExportOptions plist + signing certificate to emit. `both` emits parallel `*-AppStore.entitlements` / `*-DeveloperID.entitlements` and matching `ExportOptions-*-Mac.plist` files so a single project can be archived to either channel. - -|macNative.teamId -|Mac Native builds only. Apple Developer Team ID (alphanumeric). Falls back to `ios.release.teamId` → `ios.teamId` → `ios.debug.teamId` since most apps share a single Apple Developer Team for iOS and Mac. - -|macNative.bundleId -|Mac Native builds only. Used only when `macNative.deriveBundleId=false`. Default: `.mac`. - -|macNative.deriveBundleId -|Mac Native builds only. `true` (default) maps to Xcode's `DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER=YES` (Xcode appends `.maccatalyst` to the iOS bundle ID). Set to `false` to take the bundle ID verbatim from `macNative.bundleId`. - -|macNative.minDeploymentTarget -|Mac Native builds only. Minimum macOS version (`MACOSX_DEPLOYMENT_TARGET`). Default `10.15` — earlier versions don't support Mac Catalyst. - -|macNative.iosMinDeploymentTarget -|Mac Native builds only. iOS deployment-target floor for the Catalyst slice (`IPHONEOS_DEPLOYMENT_TARGET`). Default `13.1`. The plugin coerces the iOS slice's minimum upward when set. - -|macNative.appCategory -|Mac Native builds only. `LSApplicationCategoryType` in the generated Info.plist. Default `public.app-category.utilities`. See https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype[Apple's category list]. - -|macNative.copyright -|Mac Native builds only. `NSHumanReadableCopyright` in the Info.plist. Defaults to `Copyright (c) `. - -|macNative.signing.style -|Mac Native builds only. `automatic` (default) lets Xcode pick the signing certificate; `manual` forces the certificate identity hints below to be respected verbatim. - -|macNative.signingIdentity.appStore -|Mac Native builds only. Signing certificate identity for the App Store channel. Default `Apple Distribution`. - -|macNative.signingIdentity.developerID -|Mac Native builds only. Signing certificate identity for the Developer ID channel. Default `Developer ID Application`. - -|macNative.provisioningProfile.appStore -|Mac Native builds only. Provisioning profile name for App Store distribution — used only when `macNative.signing.style=manual`. - -|macNative.provisioningProfile.developerID -|Mac Native builds only. Provisioning profile name for Developer ID distribution — used only when `macNative.signing.style=manual`. - -|macNative.entitlements.appSandbox -|Mac Native builds only. `true` enables `com.apple.security.app-sandbox`. Default is `true` for the `appStore` channel (Mac App Store requires the sandbox), `false` for `developerID`. - -|macNative.entitlements.network.client -|Mac Native builds only. Toggles `com.apple.security.network.client`. Default `true`. - -|macNative.entitlements.network.server -|Mac Native builds only. Toggles `com.apple.security.network.server`. Default `false`. - -|macNative.entitlements.files.userSelected -|Mac Native builds only. `readwrite` (default), `readonly`, or `none`. Sets the matching `com.apple.security.files.user-selected.*` entitlement. - -|macNative.entitlements.hardenedRuntime -|Mac Native builds only. `true` enables hardened runtime restrictions. Default is `true` for `developerID` (notarization requires it), `false` for `appStore`. - -|macNative.entitlements.allowJit -|Mac Native builds only. `true` enables `com.apple.security.cs.allow-jit` for hardened runtime. ParparVM is AOT-compiled so this is `false` by default; flip when bundling a JIT-using cn1lib. - -|macNative.entitlements.extra -|Mac Native builds only. Free-form XML inserted verbatim inside the `…` of the generated entitlements plist. Use for entitlements Codename One doesn't expose individually. - -|macNative.fixedWindowSize -|Mac Native builds only. Opt-in. Format `x` — for example `1024x685`. When set, the Catalyst window's `UISceneSession.sizeRestrictions` minimum and maximum are pinned to the requested size so every launch produces a byte-identical window. Default unset, in which case the window is resizable. The CI screenshot pipeline turns this on to keep the strict-pixel golden comparison stable; production apps should leave it off. - -|desktop.width -|Width in pixels for the form in desktop builds, will be doubled for retina grade displays. Defaults to 800. - -|desktop.height -|Height in pixels for the form in desktop builds, will be doubled for retina grade displays. Defaults to 600. - -|desktop.adaptToRetina -|Boolean true/false defaults to true. When set to true some values will ve implicitly doubled to deal with retina displays and icons etc. Will use higher DPI's - -|desktop.resizable -|Boolean true/false defaults to true. Indicates whether the UI in the desktop build is resizable - -|desktop.fontSizes -|Indicates the sizes in pixels for the system fonts as a comma delimited string containing 3 numbers for small,medium,large fonts. - -|desktop.theme -|Name of the theme res file (without the ".res" extension) to use as the "native" theme. By default this is native indicating iOS theme on Mac and Windows Metro on Windows. If its something else then the app will try to load the file /themeName.res (placed in native/Java SE directory). - -|desktop.themeMac -|Same as `desktop.theme` but specific to macOS - -|desktop.themeWin -|Same as `desktop.theme` but specific to Windows - -|desktop.windowsOutput -|Can be exe or msi depending on desired results - -|desktop.win.cef -|Whether to use CEF for media and BrowserComponent instead of JavaFX in windows desktop builds. true/false. Default value is `false` (Jan 2021), but this will be changed to `true` in a future version. - -|desktop.mac.cef -|Whetherto use CEF for media or BrowserComponent instead of JavaFX in Mac desktop builds. true/false. Default value is `false` (Jan 2021), but this will be changed to `true` in a future version. - -|tvNative.enabled -|true/false (defaults to false). Adds an Apple TV (tvOS) application target to the iOS build. The tvOS app is a separate `appletvos` target built from the same Java/Kotlin sources through ParparVM (UIKit + Metal; tvOS has no OpenGL ES). Enabling it doesn't change the iOS app -- in particular it doesn't override the iOS app's `ios.metal` setting. Also turned on implicitly by `codename1.tvMain`. - -|tvNative.mainClass (a.k.a. codename1.tvMain) -|Fully-qualified tvOS lifecycle entry class. Setting it auto enables the tvOS target. If omitted while `tvNative.enabled=true`, the tvOS app reuses the phone main class. - -|tvNative.bundleId -|Bundle identifier of the tvOS app. Defaults to `.tvos`. - -|tvNative.minDeploymentTarget -|`TVOS_DEPLOYMENT_TARGET` for the tvOS target. Defaults to `13.0`. - -|tvNative.displayName -|The tvOS app name shown on Apple TV. Defaults to the app's display name. - -|tvNative.teamId -|Apple Developer Team ID used to sign the tvOS target. Falls back to the iOS team id (`ios.release.teamId` / `ios.teamId` / `ios.debug.teamId`). - -|mac.desktop-vm -|The JVM the should be bundled with Mac desktop build. Mac desktop builds only. Supported values: zuluFx8, zulu11, zuluFx11 - -|win.desktop-vm -|The JVM that should be bundled in the Windows desktop build. Windows desktop builds only. Supported values: zulu8, zuluFx8, zulu8-32bit, zuluFx8-32bit, zulu11, zuluFx11, zulu11-32bit, zuluFx11-32bit - -|windows.extensions -|Historical build hint for the discontinued UWP target. It's retained here only for legacy reference and isn't used by current supported build targets. - -|win.vm32bit -|true/false (defaults to false). Forces windows desktop builds to use the Win32 JVM instead of the 64 bit VM making them compatible with older Windows Machines. This is off by default at the moment because of a bug in JDK 8 update 112 that might cause this to fail for some cases - -|win.installDirName -|Windows desktop builds only. Overrides the default installation folder name suggested by the installer (under `Program Files`). Defaults to the application's main class name for backward compatibility. Use this build hint to set a user-friendly installation folder name (for example, `win.installDirName=My Application`). The application ID used by Windows for upgrade detection is unaffected, so existing installations continue to upgrade. - -|win.shortcutName -|Windows desktop builds only. Overrides the name used for the Start Menu shortcut, the Desktop shortcut and (when `win.launchOnStart=true`) the autostart shortcut. Defaults to the application's main class name for backward compatibility. Use this build hint to set a user-friendly shortcut label (for example, `win.shortcutName=My Application`). - -|noExtraResources -|true/false (defaults to false). Blocks codename one from injecting its own resources when set to true, the only effect this has is in slightly reducing archive size. This might have adverse effects on some features of Codename One so it isn't recommended. - -|windows.arch -|Native Windows port only (the `windows-native` build target -- not the JVM `win.*` desktop hints above). Target CPU architecture for the standalone `.exe`: `x64` (the default) or `arm64`. Accepts the usual synonyms (`x86_64`/`amd64`, `aarch64`). clang-cl cross-compiles to the chosen architecture from either host. See the link:#_working_with_the_native_windows_port[Working with the native Windows port chapter]. - -|windows.debug -|Native Windows port only. true/false (defaults to false). When `false` the `.exe` is built optimized and *stripped* -- no PDB, dead-stripped unreferenced code (`/OPT:REF`) and folded identical functions (`/OPT:ICF`) -- which is the shipping default. Set `true` to keep debug symbols (a `.pdb` next to the exe, via `RelWithDebInfo` / clang-cl `/Zi` + linker `/DEBUG`) so a native crash address can be symbolized during development. Optimizations stay on in both cases. - -|windows.sdkRoot -|Native Windows port only; used when building on a *non-Windows* host (for example a Linux build server). Path to a Windows SDK laid out by https://github.com/Jake-Shadle/xwin[`xwin splat`] (a directory containing `crt/include` and `sdk/include/um`), used to cross-compile the `.exe` with clang-cl + lld-link instead of a Visual Studio environment. If unset, the `CN1_XWIN_SYSROOT` environment variable is used. Ignored on Windows hosts, which build through Visual Studio. The same SDK serves both `windows.arch` targets (its `x86_64` / `aarch64` lib subdirs). - -|(signing certificate) -|Native Windows port only. The code-signing certificate itself isn't a build-hint argument; configure it through project settings as `codename1.windows.signing.certificate` (path to a PKCS#12 `.pfx`/`.p12` file holding the certificate + key) and `codename1.windows.signing.password`. The build uses it for both local and cloud builds -- a cloud build uploads it with the build request automatically, exactly like the iOS / Android signing certificates. When a certificate is present the produced `.exe` is Authenticode-signed with `osslsigncode` (which signs Windows PE files on any OS, so it works in the Linux build cloud); without one the exe ships unsigned (it runs, but shows "Unknown publisher" in UAC and trips SmartScreen on download). - -|windows.signing.timestampUrl -|Native Windows port only. RFC 3161 timestamp server used when signing, so the signature stays valid after the certificate expires. Default `http://timestamp.digicert.com`; set empty to disable timestamping. - -|windows.signing.digest -|Native Windows port only. Signature digest algorithm. Default `sha256`. - -|windows.signing.name / windows.signing.url -|Native Windows port only. The description and URL embedded in the signature (the "More info" shown by Windows). Default: the app's display name, and no URL. - -|windows.signing -|Native Windows port only. `true`/`false` (default `true`). Set `false` to force an unsigned build even when a certificate is available. - -|=== +.Build hints +include::_generated-build-hints.adoc[] === Versioned builds diff --git a/docs/developer-guide/_generated-build-hints.adoc b/docs/developer-guide/_generated-build-hints.adoc new file mode 100644 index 00000000000..38586afdbfd --- /dev/null +++ b/docs/developer-guide/_generated-build-hints.adoc @@ -0,0 +1,3187 @@ +// Generated from com.codename1.build.shared.BuildHints by +// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and re-run +// scripts/gen-build-hint-annotations.sh. +// +// The Annotation column names the compiler-checked form where one exists; +// those hints can be written on the application's main class instead of in +// codenameone_settings.properties. + +[cols="2,1,1,2,4"] +|=== +|Name |Type |Default |Annotation |Description + +|and.captureRecord +|string +|_(none)_ +|_(none)_ +| + +|and.facebook_permissions +|string +|_(none)_ +|_(none)_ +| + +|and.themeMode +|`auto`, `modern`, `hololight`, `legacy` +|_(none)_ +|`@Android(themeMode)` +|`auto`, `modern` / `material`, `hololight` (default for existing apps), `legacy`. `auto` and `modern` / `material` opt in to the CSS-generated Android Material 3 theme from `native-themes/android-material/theme.css`. `hololight` is Android Holo Light (what the framework shipped on API 14+ before this refactor). `legacy` loads the pre-Holo Android theme. The legacy alias `cn1.androidTheme` is still accepted, and `and.hololight=true` still maps to `hololight`. The default stays on `hololight` for existing apps until you flip in a future release. + +|android.NotificationChannel.description +|string +|`Remote notifications` +|_(none)_ +| + +|android.NotificationChannel.enableLights +|boolean +|`true` +|_(none)_ +| + +|android.NotificationChannel.enableVibration +|boolean +|`false` +|_(none)_ +| + +|android.NotificationChannel.id +|string +|`cn1-channel` +|_(none)_ +| + +|android.NotificationChannel.importance +|int +|`2` +|_(none)_ +| + +|android.NotificationChannel.lightColor +|string +|_(none)_ +|_(none)_ +| + +|android.NotificationChannel.name +|string +|`Notifications` +|_(none)_ +| + +|android.NotificationChannel.vibrationPattern +|string +|_(none)_ +|_(none)_ +| + +|android.accessibilityGuard +|boolean +|`false` +|_(none)_ +| + +|android.accessibilityGuard.allow +|string +|_(none)_ +|_(none)_ +| + +|android.accessibilityGuard.mode +|string +|`exit` +|_(none)_ +| + +|android.activity.launchMode +|string +|`singleTop` +|`@Android(activityLaunchMode)` +|Allows explicitly setting the `android:launchMode` attribute of the main activity in android. Default is "singleTop," but for some applications you may need to change this behaviour. In particular, apps that are meant to open a file type will need to set this to "singleTask." See https://developer.android.com/guide/topics/manifest/activity-element.html[Android docs for the activity element] for more information about the `android:launchMode` attribute. + +|android.activityClassBody +|string +|_(none)_ +|_(none)_ +| + +|android.activityClassImports +|string +|_(none)_ +|_(none)_ +| + +|android.adaptiveIconBackground +|string +|`#ffffff` +|_(none)_ +|Background color to use for adaptive icons when `android.enableAdaptiveIcons=true` and no background image is supplied. Defaults to `#ffffff` and is written as `@color/ic_launcher_background`. + +|android.adaptiveIconBackgroundImage +|string +|_(none)_ +|_(none)_ +|Optional path (relative to the root of the native Android project) to an image file to use as the adaptive icon background when `android.enableAdaptiveIcons=true`. If this property is set, it overrides `android.adaptiveIconBackground`. + +|android.allowBackup +|boolean +|`true` +|_(none)_ +| + +|android.androidAuto.messaging +|boolean +|`false` +|_(none)_ +| + +|android.androidAuto.minCarApiLevel +|int +|`1` +|_(none)_ +| + +|android.androidAuto.navigation +|boolean +|`false` +|_(none)_ +| + +|android.androidAuto.poi +|boolean +|`false` +|_(none)_ +| + +|android.anyDensity +|boolean +|`true` +|_(none)_ +| + +|android.apacheLegacy +|boolean +|`false` +|_(none)_ +| + +|android.appBundle +|boolean +|_(none)_ +|`@Android(appBundle)` +|Produces an Android App Bundle (.aab) rather than an APK. Required for new Play Store submissions. + +|android.appReview.version +|version +|`2.0.1` +|_(none)_ +| + +|android.ar.required +|boolean +|`false` +|_(none)_ +| + +|android.arrcompile +|string +|_(none)_ +|_(none)_ +| + +|android.arrimplementation +|string +|_(none)_ +|_(none)_ +| + +|android.asyncPaint +|boolean +|`true` +|_(none)_ +|Boolean true/false defaults to true. Toggles the Android pipeline between the legacy pipeline (false) and new pipeline (true) + +|android.background_push_handling +|boolean +|`false` +|_(none)_ +| + +|android.billingclient.version +|version +|`4.0.0` +|_(none)_ +| + +|android.blockExternalStoragePermission +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Disables the external storage (SD card) permission + +|android.blockReadMediaPermissions +|boolean +|_(none)_ +|_(none)_ +|Boolean true/false, defaults to the value of `android.blockExternalStoragePermission`. Suppresses the `READ_MEDIA_VIDEO` and `READ_MEDIA_AUDIO` permissions that playing a URI adds on API 33 and above + +|android.bluetooth.neverForLocation +|boolean +|`true` +|_(none)_ +| + +|android.bluetooth.required +|boolean +|`false` +|_(none)_ +| + +|android.buildToolsVersion +|version +|_(none)_ +|`@Android(buildToolsVersion)` +|Android build-tools version. It also selects the compile SDK, so there is no separate compile-SDK hint. + +|android.captureRecord +|string +|`enabled` +|`@Android(captureRecord)` +|Indicates whether the `RECORD_AUDIO` permission should be requested. Can be `enabled` or any other value to disable this option + +|android.carAppVersion +|version +|`1.4.0` +|_(none)_ +| + +|android.credentialsPlayServicesVersion +|string +|_(none)_ +|_(none)_ +| + +|android.credentialsVersion +|version +|`1.3.0` +|_(none)_ +| + +|android.cusom_layout +|string +|_(none)_ +|_(none)_ +| + +|android.cusom_layout* +|string +|_(none)_ +|_(properties file only)_ +|Numbered custom layout resources: android.cusom_layout1, 2, and so on. The misspelling is load-bearing -- it is the key the builder actually reads, so correcting it would silently drop the layout. + +|android.cusom_layout1 +|string +|_(none)_ +|_(none)_ +|Applies to any number of layouts as long as they're in sequence (for example, android.cusom_layout2, android.cusom_layout3 etc.). Will write the content of the argument as a layout XML file and give it the name `cusom_layout1.xml` onwards. This can be used by native code to work with XML files + +|android.customActivity +|string +|`CodenameOneActivity` +|_(none)_ +| + +|android.customTabsVersion +|version +|`1.8.0` +|_(none)_ +| + +|android.debug +|boolean +|`false` +|`@Android(debug)` +|true/false defaults to true - indicates whether to include the debug version in the build. Defaults conditionally rather than to a fixed value: when android.release is on it defaults to false, and when release is off it defaults to true, so a build that selects neither still produces something installable (AndroidGradleBuilder.java:447-451). + +|android.decouplePlayServiceVersions +|string +|_(none)_ +|_(none)_ +| + +|android.delayPushCompletion +|boolean +|`false` +|_(none)_ +| + +|android.disableR8 +|boolean +|`false` +|`@Android(disableR8)` +|Turns off R8, falling back to the older shrinker. Note that hardening requires R8, so this conflicts with harden.level. + +|android.disableR8FullMode +|boolean +|`true` +|_(none)_ +| + +|android.disableScreenshots +|boolean +|`false` +|_(none)_ +| + +|android.enableAdaptiveIcons +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Enables Android adaptive icon generation in Android Gradle builds. When enabled, Codename One generates `mipmap` launcher resources (`ic_launcher`, `ic_launcher_foreground`, and adaptive XML in `mipmap-anydpi-v26`) and uses them in the application manifest (`android:icon` and `android:roundIcon`). + +|android.enableProguard +|boolean +|`true` +|`@Android(enableProguard)` +|Boolean true/false defaults to true. Allows disabling the proguard obfuscation even on release builds, notice that this isn't recommended + +|android.excludeBolts +|boolean +|`false` +|_(none)_ +| + +|android.extendAppCompatActivity +|boolean +|`false` +|_(none)_ +| + +|android.facebookSdkVersion +|version +|`16.2.0` +|_(none)_ +| + +|android.facebook_permissions +|string +|`\"public_profile\",\"email\",\"user_friends\"` +|_(none)_ +|Permissions for Facebook used in the Android build target, applicable only if Facebook native integration is used. + +|android.file_paths +|string +|` ` +|_(none)_ +| + +|android.firebaseAnalytics +|boolean +|`false` +|_(none)_ +| + +|android.firebaseAnalyticsVersion +|version +|`21.5.0` +|_(none)_ +| + +|android.firebaseCoreVersion +|string +|_(none)_ +|_(none)_ +| + +|android.firebaseMessagingVersion +|string +|_(none)_ +|_(none)_ +| + +|android.foldableSupport +|boolean +|`false` +|_(none)_ +| + +|android.forceJava8Builder +|boolean +|`false` +|_(none)_ +| + +|android.foregroundServiceType +|string +|`dataSync` +|_(none)_ +| + +|android.fridaDebugLogging +|boolean +|_(none)_ +|_(none)_ +|Boolean true/false defaults to false. If true, it will add verbose debug logs during frida detection to show which check if fails on. + +|android.fridaDetection +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Indicates whether the app should check for the presence of the https://www.frida.re/[Frida] dynamic instrumentation toolkit on the device. If Frida is detected, the app will exit. This uses the [frida-blocker](https://github.com/shannah/frida-blocker) library to perform the frida detection. + +|android.fridaVersion +|string +|_(none)_ +|_(none)_ +|x.y.z The version of [frida-blocker](https://github.com/shannah/frida-blocker) to use to perform frida detection. This is only relevant if `android.fridaDetection=true`. If omitted, it will use the latest tested version in the build server. + +|android.fullScreenIntent +|boolean +|`false` +|_(none)_ +| + +|android.googleAdUnitId +|string +|_(none)_ +|_(none)_ +|Allows integrating admob/google play ads, this is effectively identical to google.adUnitId but only applies to Android + +|android.googleAdUnitTestDevice +|string +|`C6783E2486F0931D9D09FABC65094FDF` +|_(none)_ +|Device key used to mark a specific Android device as a test device for Google Play ads defaults to C6783E2486F0931D9D09FABC65094FDF + +|android.gpsPermission +|boolean +|`false` +|_(none)_ +|Indicates whether the GPS permission should be requested, it's autodetected by default if you use the location API. But, some code might want to explicitly define it + +|android.gradle.androidx +|list (newline delimited) +|_(none)_ +|_(none)_ +| + +|android.gradleDep +|list (`;` delimited) +|_(none)_ +|`@Android(gradleDep)` +|Gradle dependency statements to add to the app module, such as implementation 'com.example:lib:1.0'. + +|android.gradlePlugin +|list (newline delimited) +|_(none)_ +|_(none)_ +| + +|android.hce +|boolean +|`false` +|_(none)_ +| + +|android.hceAids +|string +|`F0010203040506` +|_(none)_ +| + +|android.hceCategory +|string +|`other` +|_(none)_ +| + +|android.hceDescription +|string +|_(none)_ +|_(none)_ +| + +|android.hceRequireUnlock +|boolean +|`false` +|_(none)_ +| + +|android.headphoneCallback +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. When set to true it assumes the main class has two methods: `headphonesConnected` & `headphonesDisconnected` which it invokes appropriately as needed + +|android.health.background +|boolean +|`false` +|_(none)_ +| + +|android.health.connectVersion +|string +|`1.1.0-alpha07` +|_(none)_ +| + +|android.health.history +|boolean +|`false` +|_(none)_ +| + +|android.health.privacyPolicyUrl +|string +|_(none)_ +|_(none)_ +| + +|android.health.read +|string +|_(none)_ +|_(none)_ +| + +|android.health.write +|string +|_(none)_ +|_(none)_ +| + +|android.hideOverlayWindows +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Declares the `android.permission.HIDE_OVERLAY_WINDOWS` permission needed by `DeviceIntegrity.setHideOverlayWindows()` on Android 12+, for apps that call the runtime API without enabling `android.tapjackingGuard`. A normal install-time permission, so the user sees no prompt. + +|android.hideStatusBar +|boolean +|`false` +|`@Android(hideStatusBar)` +|Hides the Android status bar. + +|android.hms.pushVersion +|string +|`6.3.0.302` +|_(none)_ +| + +|android.home.playServicesVersion +|string +|`16.0.0-beta1` +|_(none)_ +| + +|android.includeGPlayServices +|boolean +|`true` +|_(none)_ +|*Deprecated, please android.playService.+++*+++!* Indicates whether Google Play Services should be included into the build, defaults to false but that might change based on the functionality of the application and other build hints. Adding Google Play Services support allows you to use a more refined location implementation and invoke some Google specific functionality from native code. + +|android.includeMavenCentral +|boolean +|`false` +|_(none)_ +| + +|android.installLocation +|`auto`, `internalOnly`, `preferExternal` +|`auto` +|`@Android(installLocation)` +|Maps to android:installLocation manifest entry defaults to auto. Can also be set to internalOnly or preferExternal. + +|android.java8 +|string +|_(none)_ +|_(none)_ +| + +|android.keyboardOpen +|boolean +|`true` +|_(none)_ +|Boolean true/false defaults to true. Toggles the new async keyboard mode that leaves the keyboard open while you move between text components + +|android.largeScreens +|boolean +|`true` +|_(none)_ +| + +|android.licenseKey +|string +|_(none)_ +|`@Android(licenseKey)` +|The license key for the Android app, this is required if you use in-app purchase on Android + +|android.locales +|string +|_(none)_ +|_(none)_ +| + +|android.manifest.queries +|string +|_(none)_ +|_(none)_ +|Embeds XML content into the section of the Android manifest file. This is https://developer.android.com/training/package-visibility[required in Android 11 for package visibility]. See https://developer.android.com/guide/topics/manifest/queries-element[queries element Android documentation]. + +|android.messagingService +|string +|_(none)_ +|_(none)_ +| + +|android.migrateToAndroidX +|boolean +|`true` +|_(none)_ +| + +|android.min_sdk_version +|int +|`19` +|`@Android(minSdkVersion)` +|The least SDK required to run this app, the default value changes based on functionality but can be as low as 7. This corresponds to the XML attribute `android:minSdkVersion`. + +|android.mockLocation +|boolean +|`true` +|_(none)_ +|Boolean true/false defaults to true. Toggles the mock location permission which is on by default, this allows easier debugging of Android device location based services + +|android.mopubId +|string +|_(none)_ +|_(none)_ +| + +|android.multidex +|boolean +|`true` +|`@Android(multidex)` +|Boolean true/false defaults to false. Multidex allows Android binaries to reference more than 65536 methods. This slows builds a bit so you have it off by default but if you get a build error mentioning this limit you should turn this on. + +|android.newFirebaseMessaging +|boolean +|`true` +|`@Android(newFirebaseMessaging)` +|Uses the current Firebase Cloud Messaging integration. Requires AndroidX and Gradle 8.13 or newer. + +|android.nonconsumable +|string +|_(none)_ +|_(none)_ +|Comma delimited string of items that are non-consumable in the in-app purchase API + +|android.normalScreens +|boolean +|`true` +|_(none)_ +| + +|android.onCreate +|string +|_(none)_ +|_(none)_ +| + +|android.onDeviceDebug +|boolean +|`false` +|`@OnDeviceDebug(android)` +|Boolean true/false defaults to false. When `true`, the generated `AndroidManifest.xml` is marked `android:debuggable="true"`, R8/proguard is disabled, and the build is pinned to debug-only (`android.release` is forced off and `android.debug` is forced on) so a stray hint can't ship a release-signed APK that's `debuggable="true"`. Pair with the `cn1:android-on-device-debugging` Maven goal (or the bundled IntelliJ run configs) to install, launch, forward JDWP, and stream logcat through adb. Has no effect on builds that don't carry it — release builds are unaffected. See the On-Device Debugging (Android) chapter for the full flow. + +|android.permission.* +|string +|_(none)_ +|_(properties file only)_ +|true/false. Whether to include a particular permission. Preferred over android.xpermissions because it avoids conflicts with libraries. See Android's Manifest.permission documentation for the full list. The optional .maxSdkVersion suffix becomes the maxSdkVersion attribute of the generated tag, and .required marks the permission required. + +|android.playIntegrity +|boolean +|`false` +|_(none)_ +| + +|android.playIntegrity.verifyUrl +|string +|_(none)_ +|_(none)_ +| + +|android.playIntegrityVersion +|version +|`1.4.0` +|_(none)_ +| + +|android.playService.* +|string +|_(none)_ +|_(properties file only)_ +|Opts a single Google Play service in or out. The sibling .minPlayServicesVersion pins its version. + +|android.playService.ads +|boolean +|`false` +|_(none)_ +| + +|android.playService.analytics +|string +|_(none)_ +|_(none)_ +| + +|android.playService.appInvite +|boolean +|`false` +|_(none)_ +| + +|android.playService.auth +|string +|_(none)_ +|_(none)_ +| + +|android.playService.base +|string +|_(none)_ +|_(none)_ +| + +|android.playService.cast +|boolean +|`false` +|_(none)_ +| + +|android.playService.drive +|boolean +|`false` +|_(none)_ +| + +|android.playService.fitness +|boolean +|`false` +|_(none)_ +| + +|android.playService.games +|boolean +|`false` +|_(none)_ +| + +|android.playService.gcm +|string +|_(none)_ +|_(none)_ +| + +|android.playService.identity +|boolean +|`false` +|_(none)_ +| + +|android.playService.indexing +|boolean +|`false` +|_(none)_ +| + +|android.playService.location +|string +|_(none)_ +|_(none)_ +| + +|android.playService.maps +|string +|_(none)_ +|_(none)_ +| + +|android.playService.nearby +|boolean +|`false` +|_(none)_ +| + +|android.playService.panorama +|boolean +|`false` +|_(none)_ +| + +|android.playService.plus +|boolean +|`false` +|_(none)_ +| + +|android.playService.safetynet +|boolean +|`false` +|_(none)_ +| + +|android.playService.vision +|boolean +|`false` +|_(none)_ +| + +|android.playService.wallet +|boolean +|`false` +|_(none)_ +| + +|android.playService.wearable +|boolean +|`false` +|_(none)_ +| + +|android.playServicesVersion +|string +|_(none)_ +|_(none)_ +|The version number of play services to build against. Experimental. **Use with caution** as building against versions other than the server default may introduce incompatibilities with some Codename One APIs. + +|android.proguardKeep +|list (newline delimited) +|_(none)_ +|`@Android(proguardKeep)` +|Arguments for the keep option in proguard allowing you to keep a pattern of files for example, `-keep class com.mypackage.ProblemClass { *; }` + +|android.proguardKeepOverride +|string +|`Exceptions, InnerClasses, Signature, Deprecated, SourceFile, LineNumberTable, *Annotation*, EnclosingMethod` +|_(none)_ +| + +|android.pushSound +|string +|_(none)_ +|_(none)_ +| + +|android.pushVibratePattern +|string +|_(none)_ +|_(none)_ +|Comma delimited long values to describe the push pattern of vibrate used for the `setVibrate` native method + +|android.release +|boolean +|`true` +|`@Android(release)` +|true/false defaults to true - indicates whether to include the release version in the build + +|android.removeBasePermissions +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Disables the built-in permissions specifically `INTERNET` permission (that is, no networking...) + +|android.repositories +|list (newline delimited) +|_(none)_ +|`@Android(repositories)` +|Extra Gradle repositories to resolve dependencies from. + +|android.requestReadMediaPermissions +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Declares `READ_MEDIA_IMAGES`, `READ_MEDIA_VIDEO` and `READ_MEDIA_AUDIO` on API 33 and above even when the build detected no media playback. `READ_MEDIA_IMAGES` is only ever added by this hint + +|android.rootCheck +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Indicates whether the app should check for root access on the device. If root access is detected, the app will exit. + +|android.rootbeerVersion +|version +|`0.1.0` +|_(none)_ +| + +|android.shareFilter +|string +|_(none)_ +|_(none)_ +| + +|android.sharedUserId +|string +|_(none)_ +|_(none)_ +|Allows adding a manifest attribute for the sharedUserId option + +|android.sharedUserLabel +|string +|_(none)_ +|_(none)_ +|Allows adding a manifest attribute for the sharedUserLabel option + +|android.shrinkResources +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Used only in conjunction with android.enableProguard. Strips out unused resources to reduce apk size. Since 7.0 + +|android.signingV1 +|boolean +|_(none)_ +|_(none)_ +|true/false Default true. See https://source.android.com/docs/security/features/apksigning + +|android.signingV2 +|boolean +|_(none)_ +|_(none)_ +|true/false Default true. See https://source.android.com/docs/security/features/apksigning + +|android.signingV3 +|boolean +|_(none)_ +|_(none)_ +|true/false Default true. See https://source.android.com/docs/security/features/apksigning + +|android.signingV4 +|boolean +|_(none)_ +|_(none)_ +|true/false Default true. See https://source.android.com/docs/security/features/apksigning + +|android.smallScreens +|boolean +|`true` +|_(none)_ +|Boolean true/false defaults to true. Corresponds to the `android:smallScreens` XML attribute and allows disabling the support for small phones + +|android.stack_size +|string +|_(none)_ +|_(none)_ +|Size in bytes for the Android stack thread + +|android.statusbar_hidden +|boolean +|`false` +|_(none)_ +|true/false defaults to false. When set to true hides the status bar on Android devices. + +|android.store_ids +|string +|_(none)_ +|_(none)_ +| + +|android.streamMode +|string +|_(none)_ +|_(none)_ +|The mode in which the volume key should behave, defaults to OS default. Allows setting it to `music` for music playback apps + +|android.stringsXml +|string +|_(none)_ +|_(none)_ +|Allows injecting more entries into the strings.xml file using a value that includes something like this `value1value2` + +|android.style +|string +|_(none)_ +|_(none)_ +|Allows injecting more data into the `styles.xml` file right before the closing resources tag + +|android.supportScreens +|string +|_(none)_ +|_(none)_ +| + +|android.supportV4 +|boolean +|_(none)_ +|_(none)_ +|Boolean true/false defaults to false but that can change based on usage (for example, push implicitly activates this). Indicates whether the android support v4 library should be included in the build + +|android.supportv4Dep +|list (newline delimited) +|_(none)_ +|_(none)_ +| + +|android.surfaces.exactAlarms +|boolean +|`false` +|_(none)_ +| + +|android.tapjackingGuard +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Switches on tapjacking / screen-overlay protection at launch, so touches that arrive while another app's window covers this one are detected and dropped. See the security chapter. + +|android.tapjackingGuard.hideOverlays +|boolean +|`true` +|_(none)_ +|Boolean true/false defaults to true. Also asks Android 12+ to hide overlay windows drawn over the app, which is the only mitigation that covers native peer components, and declares the `HIDE_OVERLAY_WINDOWS` permission it requires. Only relevant if `android.tapjackingGuard=true`. + +|android.tapjackingGuard.mode +|string +|`block` +|_(none)_ +|`block` (default), `strict`, `report` or `off`. `block` drops gestures that start on a fully obscured window, `report` only observes, `strict` also drops touches where only part of the window is covered (which benign system UI can trigger). Only relevant if `android.tapjackingGuard=true`. + +|android.targetSDKVersion +|int +|_(none)_ +|`@Android(targetSDKVersion)` +|Indicates the Android SDK used to compile the Android build defaults to 21. Notice that not all targets will work since the source might have some limitations and not all SDK targets are installed on the build servers. + +|android.textureView +|boolean +|`false` +|_(none)_ +| + +|android.theme +|string +|`Light` +|_(none)_ +|Light or Dark defaults to Light. On Android 4+ the default Holo theme is used to render the native widgets sometimes and this indicates whether holo light or holo dark is used. This doesn't affect the Codename One theme but that might change in the future. + +|android.topDependency +|list (newline delimited) +|_(none)_ +|`@Android(topDependency)` +|Statements added to the top-level Gradle build file rather than the app module. + +|android.tv +|boolean +|`false` +|_(none)_ +|true/false (defaults to false). Marks the build as an Android TV / Google TV app. Adds the `LEANBACK_LAUNCHER` intent category to the launcher activity (so the app appears on the TV home screen), declares the `android.software.leanback` feature, makes `android.hardware.touchscreen` optional (so it installs on touchless TVs), and generates a 320×180 launcher banner (`@drawable/tv_banner`) from the app icon. The same APK still installs and runs on phones and tablets, and `CN.isTV()` returns true at runtime on a TV. + +|android.useAndroidX +|boolean +|_(none)_ +|`@Android(useAndroidX)` +|Use Android X instead of support libraries. This will also run a find/replace on all source files to replace support libraries and artifacts with AndroidX equivalents. + +|android.useGradle8 +|string +|_(none)_ +|_(none)_ +| + +|android.uses_feature.* +|string +|_(none)_ +|_(properties file only)_ +|Adds a element named by the suffix. + +|android.uses_permission.* +|string +|_(none)_ +|_(properties file only)_ +|Adds a element named by the suffix. + +|android.versionCode +|string +|_(none)_ +|_(none)_ +|Allows overriding the auto generated version number with a custom internal version number specifically used for the XML attribute `android:versionCode` + +|android.wear +|boolean +|`false` +|_(none)_ +| + +|android.wear.standalone +|string +|_(none)_ +|_(none)_ +| + +|android.web_loading_hidden +|boolean +|`false` +|_(none)_ +|true/false defaults to false - set to true to hide the progress indicator that appears when loading a web page on Android. + +|android.windowVersion +|version +|`1.3.0` +|_(none)_ +| + +|android.xactivity +|xml +|_(none)_ +|_(none)_ +|Allows injecting more attributes into the `activity` tag in the Android XML + +|android.xapplication +|xml +|_(none)_ +|`@Android(xapplication)` +|defaults to an empty string. Allows developers of native Android code to add text within the application block to define things such as widgets, services etc. + +|android.xapplication_attr +|xml +|_(none)_ +|_(none)_ +|Allows injecting more attributes into the `application`` tag in the Android XML + +|android.xgradle +|list (newline delimited) +|_(none)_ +|`@Android(xgradle)` +|Arbitrary text spliced into the generated app-module Gradle file. + +|android.xgradle_default_config +|list (newline delimited) +|_(none)_ +|_(none)_ +| + +|android.xintent_filter +|xml +|_(none)_ +|_(none)_ +|Allows adding an intent filter to the main android activity + +|android.xlargeScreens +|boolean +|`true` +|_(none)_ +| + +|android.xlayout_attr +|string +|_(none)_ +|_(none)_ +| + +|android.xmanifest +|xml +|_(none)_ +|_(none)_ +| + +|android.xpermissions +|xml +|_(none)_ +|`@Android(xpermissions)` +|more permissions for the Android manifest + +|desktop.adaptToRetina +|boolean +|`true` +|`@Desktop(adaptToRetina)` +|Boolean true/false defaults to true. When set to true some values will ve implicitly doubled to deal with retina displays and icons etc. Will use higher DPI's + +|desktop.fontSizes +|string +|_(none)_ +|_(none)_ +|Indicates the sizes in pixels for the system fonts as a comma delimited string containing 3 numbers for small,medium,large fonts. + +|desktop.fullscreen +|boolean +|`false` +|`@Desktop(fullscreen)` +|Starts the desktop build in full-screen mode. + +|desktop.height +|int +|`600` +|`@Desktop(height)` +|Height in pixels for the form in desktop builds, will be doubled for retina grade displays. Defaults to 600. + +|desktop.interactiveScrollbars +|boolean +|`true` +|`@Desktop(interactiveScrollbars)` +|Enables grab-able, click-to-page desktop scrollbars. + +|desktop.resizable +|boolean +|`true` +|`@Desktop(resizable)` +|Boolean true/false defaults to true. Indicates whether the UI in the desktop build is resizable + +|desktop.theme +|string +|_(none)_ +|_(none)_ +|Name of the theme res file (without the ".res" extension) to use as the "native" theme. By default this is native indicating iOS theme on Mac and Windows Metro on Windows. If its something else then the app will try to load the file /themeName.res (placed in native/Java SE directory). + +|desktop.themeMac +|string +|_(none)_ +|_(none)_ +|Same as `desktop.theme` but specific to macOS + +|desktop.themeWin +|string +|_(none)_ +|_(none)_ +|Same as `desktop.theme` but specific to Windows + +|desktop.title +|string +|_(none)_ +|_(none)_ +| + +|desktop.titleBar +|`native`, `custom`, `toolbar` +|`native` +|`@Desktop(titleBar)` +|How the desktop window is framed: native for the OS title bar and menu bar, custom for an undecorated window with a Codename One drawn title bar, or toolbar for the legacy in-app Toolbar. An unrecognized value falls back to native with a warning. + +|desktop.width +|int +|`800` +|`@Desktop(width)` +|Width in pixels for the form in desktop builds, will be doubled for retina grade displays. Defaults to 800. + +|desktop.win.cef +|boolean +|_(none)_ +|_(none)_ +|Whether to use CEF for media and BrowserComponent instead of JavaFX in windows desktop builds. true/false. Default value is `false` (Jan 2021), but this will be changed to `true` in a future version. + +|desktop.windowsOutput +|string +|_(none)_ +|_(none)_ +|Can be exe or msi depending on desired results + +|KeepScreenOn +|boolean +|`false` +|_(none)_ +| + +|androidx.appcompat.version +|string +|_(none)_ +|_(none)_ +| + +|block_server_registration +|boolean +|_(none)_ +|_(none)_ +|true/false flag defaults to false. By default Codename One applications register with the Codename One server. Setting this to true blocks them from sending information to the Codename One cloud, which is kept for statistical purposes and may be used to provide more installation stats in the future. + +|build.cn1Version +|string +|_(none)_ +|_(none)_ +|Pro/Enterprise only. Pins the cloud build to a specific released Codename One version using the Maven release scheme (for example `7.0.182`), or to `master` to build against the current development head. The build server fetches that version's framework artifacts. Pro accounts can target versions published within the last two months; Enterprise within the last six months. Requesting an older version, a version that was never published, or using this hint without a Pro/Enterprise subscription fails the build with an explanatory error. See Versioned builds. + +|build.incSources +|string +|_(none)_ +|_(none)_ +| + +|build.testReporter +|string +|_(none)_ +|_(none)_ +| + +|build.unitTest +|string +|_(none)_ +|_(none)_ +| + +|cn1.androidTheme +|string +|_(none)_ +|_(none)_ +| + +|cn1.buildKey +|string +|_(none)_ +|_(none)_ +| + +|cn1.entitled +|boolean +|`true` +|_(none)_ +| + +|cn1.harden.forceOff +|string +|_(none)_ +|_(none)_ +| + +|cn1.hardenLevel +|string +|`off` +|_(none)_ +| + +|cn1.hardened +|boolean +|`false` +|_(none)_ +| + +|cn1.hardening.libraryJars +|string +|_(none)_ +|_(none)_ +| + +|cn1.mappingId +|string +|_(none)_ +|_(none)_ +| + +|cn1.nativeTheme +|string +|_(none)_ +|_(none)_ +| + +|codename1.mac.appid +|string +|_(none)_ +|_(none)_ +|Mac Native cloud builds only. The Mac bundle identifier registered in App Store Connect / Apple Developer. Distinct from `codename1.ios.appid` because Apple treats the iOS and Mac App Store records as separate products. Required for cloud Mac builds. + +|codename1.mac.certificate +|string +|_(none)_ +|_(none)_ +|Mac Native cloud builds only. Path to the `.p12` file containing the Mac signing certificate(s) — _Mac App Distribution_ (3rd Party Mac Developer Application) for App Store builds, _Developer ID Application_ for Developer ID builds, or both bundled into the same P12 when `macNative.distribution=both`. Not interchangeable with the iOS distribution certificate. Required for cloud Mac builds. + +|codename1.mac.certificatePassword +|string +|_(none)_ +|_(none)_ +|Mac Native cloud builds only. Password to unlock the P12 referenced by `codename1.mac.certificate`. Required for cloud Mac builds. + +|codename1.mac.provision +|string +|_(none)_ +|_(none)_ +|Mac Native cloud builds only. Path to the Mac provisioning profile (`.provisionprofile`). Apple issues distinct provisioning profiles for Mac App Store and Developer ID distribution — pass the one that matches the chosen channel. + +|db.legacy +|string +|_(none)_ +|_(none)_ +| + +|delayPushCompletion +|boolean +|`false` +|_(none)_ +| + +|facebook.appId +|string +|`706695982682332` +|`@Build(facebookAppId)` +|The application ID for an app that requires native Facebook login integration, this defaults to null which means native Facebook support shouldn't be in the app + +|facebook.clientToken +|string +|_(none)_ +|_(none)_ +|The client token for an app that requires native Facebook login integration, this is required if the facebook.appId is set. + +|gcm.sender_id +|string +|_(none)_ +|`@Build(gcmSenderId)` +|The Android/chrome push identifier, see the push section for more details + +|google.adUnitId +|string +|_(none)_ +|_(none)_ +|Allows integrating Admob/Google Play ads into the application see link:https://www.codenameone.com/blog/adding-google-play-ads.html[this] + +|gradleDependencies +|list (newline delimited) +|_(none)_ +|_(none)_ +| + +|harden.* +|string +|_(none)_ +|_(properties file only)_ +|The whole hardening namespace is swept into the hardening engine's configuration, so a hint added there reaches it without a dedicated reader. + +|harden.*.enabled +|string +|_(none)_ +|_(properties file only)_ +|Enables or disables hardening for one platform slice. + +|harden.allowUnhardenedLocalBuild +|boolean +|`false` +|`@Hardening(allowUnhardenedLocalBuild)` +|Permits a local or source build to run with hardening requested but not applied. Without it such a build is refused, so a hardened app is never shipped from a target that cannot actually harden it. + +|harden.controlFlow +|`off`, `on` +|_(none)_ +|`@Hardening(controlFlow)` +|Overrides control-flow obfuscation independently of harden.level. + +|harden.ios.enabled +|boolean +|`true` +|_(none)_ +| + +|harden.keep +|text_block +|_(none)_ +|`@Hardening(keep)` +|Keep rules in ProGuard syntax, one per line, for classes that are resolved by name at runtime and so cannot be found by the automatic analysis. Same syntax as android.proguardKeep, so existing rules port directly. Rules are separated by newlines only, because a semicolon is legal inside a rule body such as { *; }. + +|harden.level +|`off`, `standard`, `aggressive`, `paranoid` +|`off` +|`@Hardening(level)` +|Master switch for app hardening: off, standard, aggressive or paranoid. An unrecognized value fails the build rather than being quietly treated as off. + +|harden.mac.enabled +|boolean +|`true` +|_(none)_ +| + +|harden.rename +|boolean +|_(none)_ +|`@Hardening(rename)` +|Overrides symbol renaming independently of harden.level. + +|harden.strings +|`off`, `constants`, `all` +|_(none)_ +|`@Hardening(strings)` +|Overrides string obfuscation independently of harden.level: off, constants or all. + +|harden.tv.enabled +|boolean +|`true` +|_(none)_ +| + +|harden.watch.enabled +|boolean +|`true` +|_(none)_ +| + +|java.version +|int +|`8` +|_(none)_ +|Valid values include 5 or 8. Indicates the JVM version that should be used for server compilation, this is defined by default for newly created apps based on the Java 8 mode selection + +|mac.desktop-vm +|string +|_(none)_ +|_(none)_ +|The JVM the should be bundled with Mac desktop build. Mac desktop builds only. Supported values: zuluFx8, zulu11, zuluFx11 + +|maps.provider +|string +|_(none)_ +|_(none)_ +| + +|nativeTheme +|`modern`, `legacy`, `custom` +|_(none)_ +|`@Build(nativeTheme)` +|`modern`, `legacy`, `custom` (default unset). Cross-platform override that sets both `ios.themeMode` and `and.themeMode` together when those aren't set explicitly. `modern` = liquid glass + Material 3, `legacy` = iOS 7 flat + Holo Light, `custom` disables the framework native theme entirely. The legacy alias `cn1.nativeTheme` is still accepted. + +|noExtraResources +|boolean +|`false` +|`@Build(noExtraResources)` +|true/false (defaults to false). Blocks codename one from injecting its own resources when set to true, the only effect this has is in slightly reducing archive size. This might have adverse effects on some features of Codename One so it isn't recommended. + +|requireKotlinStdlib +|string +|_(none)_ +|_(none)_ +| + +|tvMain +|string +|_(none)_ +|_(none)_ +| + +|var.* +|string +|_(none)_ +|_(properties file only)_ +|Defines a variable that any other hint can interpolate as ${var.name}, with ${var.name:default} for a fallback. + +|vserv.allowSkipping +|boolean +|`true` +|_(none)_ +| + +|vserv.category +|int +|`29` +|_(none)_ +| + +|vserv.countryCode +|string +|`null` +|_(none)_ +| + +|vserv.locale +|string +|`en_US` +|_(none)_ +| + +|vserv.networkCode +|string +|`null` +|_(none)_ +| + +|vserv.scaleMode +|boolean +|`false` +|_(none)_ +| + +|vserv.transition +|int +|`300000` +|_(none)_ +| + +|vserv.zone +|string +|_(none)_ +|_(none)_ +| + +|watchMain +|string +|_(none)_ +|_(none)_ +| + +|watchStandalone +|boolean +|`false` +|_(none)_ +| + +|xxx.minPlayServicesVersion +|string +|_(none)_ +|_(none)_ +|This is a special case build hint. You can use any prefix to the build hint and the convention is to use your cn1lib name. It's identical to `android.minPlayServicesVersion` with the exception that the "highest version wins." That way if your cn1lib requires play services 9+ and uses: `myLib.minPlayServicesVersion=9.0.0` and another library has `otherLib.minPlayServicesVersion=10.0.0` then play services will be 10.0.0 + +|ios.*.appext.* +|string +|_(none)_ +|_(properties file only)_ +|Per-app-extension signing. ios.debug.appext..* and ios.release.appext..* are collapsed to unqualified keys before the request is sent. + +|ios.NFCReaderUsageDescription +|string +|_(none)_ +|_(none)_ +| + +|ios.NS*UsageDescription +|string +|_(none)_ +|_(properties file only)_ +|Info.plist privacy strings. The commonly used keys are catalogued individually and exposed through @IosPrivacy; this entry covers the open tail that the builder sweeps by prefix. + +|ios.NSBonjourServices +|string +|_(none)_ +|_(none)_ +| + +|ios.NSCalendarsFullAccessUsageDescription +|string +|`This app uses your calendars to read and schedule events.` +|`@IosPrivacy(calendarsFullAccessUsageDescription)` +| + +|ios.NSCalendarsUsageDescription +|string +|_(none)_ +|`@IosPrivacy(calendarsUsageDescription)` +| + +|ios.NSCalendarsWriteOnlyAccessUsageDescription +|string +|`This app uses your calendar to schedule events.` +|`@IosPrivacy(calendarsWriteOnlyAccessUsageDescription)` +| + +|ios.NSCameraUsageDescription +|string +|_(none)_ +|`@IosPrivacy(cameraUsageDescription)` +| + +|ios.NSHealthShareUsageDescription +|string +|_(none)_ +|`@IosPrivacy(healthShareUsageDescription)` +| + +|ios.NSHealthUpdateUsageDescription +|string +|_(none)_ +|`@IosPrivacy(healthUpdateUsageDescription)` +| + +|ios.NSLocalNetworkUsageDescription +|string +|_(none)_ +|`@IosPrivacy(localNetworkUsageDescription)` +| + +|ios.NSLocationAlwaysAndWhenInUseUsageDescription +|string +|_(none)_ +|`@IosPrivacy(locationAlwaysAndWhenInUseUsageDescription)` +| + +|ios.NSLocationAlwaysUsageDescription +|string +|_(none)_ +|`@IosPrivacy(locationAlwaysUsageDescription)` +| + +|ios.NSLocationWhenInUseUsageDescription +|string +|_(none)_ +|`@IosPrivacy(locationWhenInUseUsageDescription)` +| + +|ios.NSMicrophoneUsageDescription +|string +|_(none)_ +|`@IosPrivacy(microphoneUsageDescription)` +| + +|ios.NSRemindersFullAccessUsageDescription +|string +|`This app uses your reminders to read and schedule tasks.` +|`@IosPrivacy(remindersFullAccessUsageDescription)` +| + +|ios.NSRemindersUsageDescription +|string +|_(none)_ +|`@IosPrivacy(remindersUsageDescription)` +| + +|ios.NSXXXUsageDescription +|string +|_(none)_ +|_(none)_ +|iOS privacy flags for using certain APIs. Starting with Xcode 8, you're required to add usage description strings for certain APIs. Find a full list of the available keys in https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html[Apple's docs]. Some relevant ones include `ios.NSCameraUsageDescription`, `ios.NSContactsUsageDescription`, `ios.NSLocationAlwaysUsageDescription`, `NSLocationUsageDescription`, `ios.NSMicrophoneUsageDescription`, `ios.NSPhotoLibraryAddUsageDescription`, `ios.NSSpeechRecognitionUsageDescription`, `ios.NSSiriUsageDescription` + +|ios.UIRequiredDeviceCapabilities +|string +|_(none)_ +|_(none)_ +| + +|ios.actionSheetStyle +|string +|_(none)_ +|_(none)_ +| + +|ios.add_libs +|list (`;` delimited) +|_(none)_ +|`@Ios(addLibs)` +|A semicolon separated list of libraries that should be linked to the app to build it + +|ios.afterFinishLaunching +|string +|_(none)_ +|_(none)_ +|Objective-C code that can be injected into the iOS app delegate at the bottom of the body of the didFinishLaunchingWithOptions callback method + +|ios.appAttest +|boolean +|`false` +|_(none)_ +| + +|ios.appAttest.environment +|string +|_(none)_ +|_(none)_ +| + +|ios.appUsesNonExemptEncryption +|string +|_(none)_ +|_(none)_ +| + +|ios.app_groups +|string +|_(none)_ +|_(none)_ +|Space-delimited list of app groups that this app belongs to as described in https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW19[Apple's documentation]. These are added to the entitlements file with key `com.apple.security.application-groups`. + +|ios.appext.NAME.provisioningURL +|string +|_(none)_ +|_(none)_ +|Cloud device builds only. URL of the provisioning profile for a generic app extension dropped into `ios/app_extensions/NAME/` (or a generated extension such as `CN1Widgets`), used when the extension folder doesn't bundle a `.mobileprovision` itself. The profile is installed on the build machine and added to the export options per bundle id. Used for both debug and release builds unless a qualified variant (below) is set. An extension is signed against its own App ID, so a device build with no profile for it -- by any of the three carriers -- is refused unless the app's own profile is a wildcard that covers the extension's bundle id. + +|ios.applicationDidEnterBackground +|string +|_(none)_ +|_(none)_ +|Objective-C code that can be injected into the iOS callback method (message) `applicationDidEnterBackground`. + +|ios.applicationQueriesSchemes +|list (`,` delimited) +|_(none)_ +|`@Ios(applicationQueriesSchemes)` +|Comma separated list of url schemes that `canExecute` will respect on iOS. If the url scheme isn't mentioned here `canExecute` will return false starting with iOS 9. Notice that this collides with `ios.plistInject` when used with the `LSApplicationQueriesSchemes...` value so you should use one or the other. For example, to enable `canExecute` for a url like `myurl://xys` you can use: `myurl,myotherurl` + +|ios.application_exits +|boolean +|_(none)_ +|_(none)_ +|true/false (defaults to false). Indicates whether the application should exit on home button press. The default is to exit, leaving the application running is only tested at the moment. + +|ios.associatedDomains +|string +|_(none)_ +|_(none)_ +|Comma-delimited list of domains associated with this app. Each domain should be prefixed by a supported prefix. For example, "applinks:" or "webcredentials:." See https://developer.apple.com/documentation/security/password_autofill/setting_up_an_app_s_associated_domains?language=objc[Apple's documentation on Associated domains] for more information. + +|ios.backgroundProcessingIds +|string +|_(none)_ +|_(none)_ +| + +|ios.background_modes +|string +|_(none)_ +|_(none)_ +| + +|ios.beforeFinishLaunching +|text_block +|_(none)_ +|`@Ios(beforeFinishLaunching)` +|Objective-C code that can be injected into the iOS app delegate at the top of the body of the didFinishLaunchingWithOptions callback method + +|ios.bitcode +|boolean +|`false` +|_(none)_ +|true/false defaults to false. Enables bitcode support for the build. + +|ios.blockScreenshotsOnEnterBackground +|boolean +|`false` +|_(none)_ +|true/false (defaults to false). Indicates that app should prevent iOS from taking screenshots when app enters background. Described https://shannah.github.io/cn1-recipes/#_hiding_sensitive_data_when_entering_background[here]. + +|ios.bluetooth.background +|string +|_(none)_ +|_(none)_ +| + +|ios.buildType +|string +|`debug` +|_(none)_ +| + +|ios.bundleVersion +|version +|_(none)_ +|`@Ios(bundleVersion)` +|Indicates the version number of the bundle, this is useful if you want to create a minor version number change for the beta testing support + +|ios.carplay.audio +|boolean +|`false` +|_(none)_ +| + +|ios.carplay.messaging +|boolean +|`false` +|_(none)_ +| + +|ios.carplay.navigation +|boolean +|`false` +|_(none)_ +| + +|ios.carplay.poi +|boolean +|`false` +|_(none)_ +| + +|ios.convertSignalsToExceptions +|boolean +|`true` +|_(none)_ +| + +|ios.criticalAlerts +|boolean +|`false` +|_(none)_ +| + +|ios.crypto.gcm +|boolean +|`false` +|_(none)_ +| + +|ios.debug.archs +|string +|_(none)_ +|_(none)_ +|Can be set to "armv7" to force iOS debug builds to be 32 bit. By default, debug builds are 64 bit only. + +|ios.debug.distributionMethod +|string +|_(none)_ +|_(none)_ +|Specifies distribution type for debug iOS builds only. This is used for enterprise or ad-hoc builds (using values "enterprise" and "ad-hoc" respectively). + +|ios.debug.teamId +|string +|_(none)_ +|_(none)_ +|Specifies the team ID associated with the iOS debug provisioning profile and certificate. + +|ios.delayPushCompletion +|boolean +|`false` +|_(none)_ +| + +|ios.dependencyManager +|`auto`, `cocoapods`, `spm`, `both`, `none` +|`auto` +|`@Ios(dependencyManager)` +|Which native dependency manager to use: auto picks one from whichever of ios.pods and ios.spm.packages is set, and cocoapods, spm or both require the matching hint to be set. An unrecognized value fails the build. + +|ios.deployment_target +|version +|_(none)_ +|`@Ios(deploymentTarget)` +|Minimum iOS version the build targets. Set it to the lowest iOS you actually support; a higher value excludes older devices from the App Store listing. + +|ios.detectJailbreak +|boolean +|`false` +|_(none)_ +|true/false (defaults to false). When true, the iOS app will exit on launch if it detects that it's running on a jailbroken device. + +|ios.devLocale +|string +|_(none)_ +|_(none)_ +| + +|ios.disableScreenshots +|boolean +|`false` +|_(none)_ +| + +|ios.distributionMethod +|string +|_(none)_ +|_(none)_ +|Specifies distribution type for debug iOS builds. This is used for enterprise or ad-hoc builds (using values "enterprise" and "ad-hoc" respectively). + +|ios.enableAutoplayVideo +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Makes videos "autoplay" when loaded on iOS + +|ios.enableBadgeClear +|boolean +|`true` +|_(none)_ +|Boolean true/false defaults to true. Clears the badge value with every load of the app, this is useful if the app doesn't manually keep track of number values for the badge + +|ios.enableGalleryMultiselect +|boolean +|`false` +|_(none)_ +| + +|ios.enableStatusBar7 +|boolean +|`true` +|_(none)_ +| + +|ios.entitlements.* +|string +|_(none)_ +|_(properties file only)_ +|Adds an arbitrary entitlement key to the generated entitlements file. + +|ios.entitlements.com.apple.developer +|string +|_(none)_ +|_(none)_ +| + +|ios.entitlements.com.apple.developer.applesignin +|string +|_(none)_ +|_(none)_ +| + +|ios.entitlements.com.apple.developer.healthkit +|boolean +|`false` +|_(none)_ +| + +|ios.entitlements.com.apple.developer.homekit +|string +|_(none)_ +|_(none)_ +| + +|ios.entitlements.com.apple.developer.networking.HotspotConfiguration +|string +|_(none)_ +|_(none)_ +| + +|ios.entitlements.com.apple.developer.nfc.hce +|string +|_(none)_ +|_(none)_ +| + +|ios.entitlements.com.apple.developer.nfc.readersession.formats +|string +|_(none)_ +|_(none)_ +| + +|ios.entitlementsInject +|xml +|_(none)_ +|_(none)_ +|Content to inject into the iOS entitlements file. This should be in the Plist XML format. See https://developer.apple.com/documentation/bundleresources/entitlements?language=objc[Apple Entitlements Documentation]. + +|ios.facebook.usePods +|boolean +|`true` +|_(none)_ +| + +|ios.facebook.version +|string +|`~>5.6.0` +|_(none)_ +| + +|ios.facebook_permissions +|string +|_(none)_ +|_(none)_ +|Permissions for Facebook used in the Android build target, applicable only if Facebook native integration is used. + +|ios.failOnWarning +|boolean +|`false` +|_(none)_ +| + +|ios.fieldNullChecks +|boolean +|`false` +|_(none)_ +| + +|ios.fileSharingEnabled +|boolean +|`false` +|_(none)_ +| + +|ios.firebaseAnalytics +|boolean +|`false` +|_(none)_ +| + +|ios.firebaseAnalyticsVersion +|string +|_(none)_ +|_(none)_ +| + +|ios.force64 +|boolean +|`false` +|_(none)_ +| + +|ios.generateSplashScreens +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Enables legacy generation of splash screen images instead of the current launch storyboards. + +|ios.glAppDelegateBody +|string +|_(none)_ +|_(none)_ +|Objective-C code that can be injected into the iOS app delegate within the body of the file before the end. This only makes sence for methods that aren't already declared in the class + +|ios.glAppDelegateHeader +|text_block +|_(none)_ +|`@Ios(glAppDelegateHeader)` +|Objective-C code that can be injected into the iOS app delegate at the top of the file. For example, if you need to include headers or make special imports for other injected code + +|ios.googleAdUnitId +|string +|_(none)_ +|_(none)_ +|Allows integrating admob/google play ads, this is effectively identical to google.adUnitId but only applies to iOS + +|ios.googleAdUnitIdPadding +|string +|_(none)_ +|_(none)_ +|Indicates the amount of padding to pass to the Google Ads placed at the bottom of the screen with `google.adUnitId` + +|ios.googleAdUnitTestDevice +|string +|`97cfc76e5efbc6dfa7eb2e6857b613a0` +|_(none)_ +| + +|ios.gplus.clientId +|string +|_(none)_ +|_(none)_ +| + +|ios.hceAids +|string +|_(none)_ +|_(none)_ +| + +|ios.headphoneCallback +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. When set to true it assumes the main class has two methods: `headphonesConnected` & `headphonesDisconnected` which it invokes appropriately as needed + +|ios.health.backgroundDelivery +|boolean +|`false` +|_(none)_ +| + +|ios.health.recalibrateEstimates +|boolean +|`false` +|_(none)_ +| + +|ios.health.required +|boolean +|`false` +|_(none)_ +| + +|ios.home.appGroup +|string +|_(none)_ +|_(none)_ +| + +|ios.home.commissioning +|boolean +|`true` +|_(none)_ +| + +|ios.home.commissioning.buildSettings.* +|string +|_(none)_ +|_(properties file only)_ +|Overrides an Xcode build setting for the Matter commissioning extension. + +|ios.home.commissioning.displayName +|string +|_(none)_ +|_(none)_ +| + +|ios.home.commissioning.fabric +|string +|_(none)_ +|_(none)_ +| + +|ios.home.commissioning.vendorId +|string +|`0xFFF1` +|_(none)_ +| + +|ios.home.required +|boolean +|`false` +|_(none)_ +| + +|ios.includeNullChecks +|boolean +|`true` +|_(none)_ +| + +|ios.includePush +|boolean +|`false` +|`@Ios(includePush)` +|true/false (defaults to false). Whether to include the push capabilities in the iOS build. Notice that the IDE plugin has an "Include Push" check box you *should* use under the iOS section. + +|ios.intents.appIntents +|boolean +|`true` +|_(none)_ +| + +|ios.intents.minDeploymentTarget +|string +|_(none)_ +|_(none)_ +| + +|ios.interface_orientation +|string +|_(none)_ +|`@Ios(interfaceOrientation)` +|UIInterfaceOrientationPortrait by default. Indicates the orientation, one or more of (separated by colon :): `UIInterfaceOrientationPortrait`, `UIInterfaceOrientationPortraitUpsideDown`, `UIInterfaceOrientationLandscapeLeft`, `UIInterfaceOrientationLandscapeRight`. Notice that the IDE plugin has an "Interface Orientation" combo box you *should* use under the iOS section. + +|ios.keyboardOpen +|boolean +|`true` +|_(none)_ +|Flips between iOS keyboard open mode and autofold keyboard mode. Defaults to true which means the keyboard will remain open and not fold automatically when editing moves to another field. + +|ios.keychainAccessGroup +|string +|_(none)_ +|_(none)_ +|Space-delimited list of keychain access groups that this app has access to as described in https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html#//apple_ref/doc/uid/TP30000897-CH204-SW11[Apple's documentation]. These are added to the entitlements file with the key `keychain-access-groups`. + +|ios.launchPlaceholder +|boolean +|`true` +|_(none)_ +| + +|ios.launchStoryboardName +|string +|`LaunchScreen` +|_(none)_ +| + +|ios.locationUsageDescription +|string +|_(none)_ +|_(none)_ +|This flag is required for iOS 8 and newer if you're using the location API. It needs to include a description of the reason for which you need access to the users location + +|ios.lowMemCamera +|boolean +|`false` +|_(none)_ +| + +|ios.metal +|boolean +|`true` +|_(none)_ +|Boolean true/false defaults to true. Selects the Metal rendering backend (`CAMetalLayer`) over the legacy OpenGL ES 2 path (`CAEAGLLayer`). Metal is the supported iOS graphics API; OpenGL ES is deprecated. Set to `false` to opt out if you hit a Metal-only rendering regression. See link:#_metal_renderer[Working with iOS / Metal renderer] for details. + +|ios.metal.colorSpace +|string +|`sRGB` +|_(none)_ +|Selects the `CAMetalLayer.colorspace` for the Metal renderer. Accepts `sRGB` (default), `displayP3`, `deviceRGB`, `linearSRGB`, `extendedSRGB`, `extendedLinearSRGB`, or `none`. Has no effect when `ios.metal=false`. See link:#_choosing_a_color_space_for_the_metal_renderer[Working with iOS / Choosing a color space] for the full table. + +|ios.minDeploymentTarget +|version +|`6.0` +|`@Ios(minDeploymentTarget)` +|The null and empty-string reads of this hint are presence checks; 6.0 is the substantive default (IPhoneBuilder.java:4671). + +|ios.mopubAdSize +|string +|`MOPUB_BANNER_SIZE` +|_(none)_ +| + +|ios.mopubId +|string +|_(none)_ +|_(none)_ +| + +|ios.mopubTabletAdSize +|string +|`MOPUB_LEADERBOARD_SIZE` +|_(none)_ +| + +|ios.mopubTabletId +|string +|_(none)_ +|_(none)_ +| + +|ios.multitasking +|boolean +|`true` +|_(none)_ +|Set to true to enable iOS multitasking and split-screen support. This only works if `ios.xcode_verson=9.2`. + +|ios.newPipeline +|boolean +|_(none)_ +|_(none)_ +|Boolean true/false defaults to true. Allows toggling the OpenGL ES 2.0 drawing pipeline off to the older OGL ES 1.0 pipeline. + +|ios.newStorageLocation +|boolean +|`true` +|`@Ios(newStorageLocation)` +|true/false defaults to false but defined on new projects as true by default. This changes the storage directory on iOS from using caches to using the documents directory which is the recommended location but might break compatibility. This is described in https://github.com/codenameone/CodenameOne/issues/1480[this issue] + +|ios.noUIWebView +|boolean +|`true` +|_(none)_ +| + +|ios.no_strip +|boolean +|`false` +|_(none)_ +| + +|ios.notificationPermissionAtLaunch +|boolean +|`false` +|_(none)_ +|true/false (defaults to false). Backward-compatibility flag for the pre-issue-#4876 behavior. By default, the iOS notification permission prompt is deferred until the app calls `Push.register()` or schedules a `LocalNotification`, matching the Android flow and giving the developer a chance to display a rationale screen first. Set this hint to `true` to restore the legacy behavior in which the prompt fires automatically inside `application:didFinishLaunchingWithOptions:` as soon as the app launches. Existing apps relying on the prompt being shown at launch should set this to `true`; new apps should leave it disabled and trigger the prompt explicitly when they're ready to ask for permission. + +|ios.objC +|boolean +|`false` +|`@Ios(objC)` +|Added the `-ObjC` compile flag to the project files which some native libraries require + +|ios.onDeviceDebug +|boolean +|`false` +|`@OnDeviceDebug(ios)` +|Boolean true/false defaults to false. When `true`, the iOS build links a small JDWP listener thread (`cn1_debugger`) into the binary and the ParparVM translator emits source-line and locals metadata so a desktop proxy can serve the running app to any JDWP-speaking debugger. Has no effect on release builds. See the On-Device Debugging (iOS) chapter for the full flow. + +|ios.onDeviceDebug.proxyHost +|string +|`127.0.0.1` +|`@OnDeviceDebug(iosProxyHost)` +|Hostname or IP address the device-side listener dials to reach the desktop proxy. Default `127.0.0.1` (correct for the native iOS simulator). For a physical device, set this to the developer laptop's LAN IP. Has no effect unless `ios.onDeviceDebug=true`. + +|ios.onDeviceDebug.proxyPort +|int +|`55333` +|`@OnDeviceDebug(iosProxyPort)` +|TCP port on `ios.onDeviceDebug.proxyHost` where the proxy is listening for the device. Default `55333`. Has no effect unless `ios.onDeviceDebug=true`. + +|ios.onDeviceDebug.waitForAttach +|boolean +|`false` +|`@OnDeviceDebug(iosWaitForAttach)` +|Boolean true/false defaults to false. When `true`, the app blocks at startup until the proxy connects and the IDE tells the VM to continue. Useful when the breakpoint to investigate fires during app boot. Has no effect unless `ios.onDeviceDebug=true`. + +|ios.openURLInject +|xml +|_(none)_ +|_(none)_ +| + +|ios.optimizer +|string +|`on` +|_(none)_ +| + +|ios.plistInject +|xml +|_(none)_ +|`@Ios(plistInject)` +|entries to inject into the iOS plist file during build. + +|ios.pods +|list (`,` delimited) +|_(none)_ +|`@Ios(pods)` +|A comma separated list of https://cocoapods.org/[Cocoa Pods] that should be linked to the app to build it. For example, `AFNetworking ~> 2.6, ORStackView ~> 3.0, SwiftyJSON ~> 2.3` + +|ios.pods.build.* +|string +|_(none)_ +|_(properties file only)_ +|Overrides an Xcode build setting for the generated CocoaPods project. + +|ios.pods.build.CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES +|string +|_(none)_ +|_(none)_ +| + +|ios.pods.build.CLANG_ENABLE_MODULES +|string +|_(none)_ +|_(none)_ +| + +|ios.pods.platform +|version +|_(none)_ +|`@Ios(podsPlatform)` +|Sets the Cocoapods 'platform' for the Cocoapods. Some Cocoapods require a minimum platform level. For example, `ios.pods.platform=7.0`. + +|ios.pods.sources +|list (`,` delimited) +|_(none)_ +|`@Ios(podsSources)` +|Extra CocoaPods spec repositories to search, in addition to the default trunk. + +|ios.pods.use_frameworks! +|boolean +|`false` +|_(none)_ +| + +|ios.prerendered_icon +|boolean +|`false` +|`@Ios(prerenderedIcon)` +|true/false defaults to false. The iOS build process adapts the submitted icon for iOS conventions (adding an overlay) that might not be appropriate on some icons. Setting this to true leaves the icon unchanged (only scaled). + +|ios.project_type +|`ios`, `ipad`, `iphone` +|`ios` +|`@Ios(projectType)` +|one of ios, ipad, iphone (defaults to ios). Indicates whether the resulting binary is targeted to the iphone only or ipad only. Notice that the IDE plugin has a "Project Type" combo box you *should* use under the iOS section. + +|ios.release.archs +|string +|_(none)_ +|_(none)_ +|Can be set to "arm64" to only build iOS release builds for 64 bit. By default, release builds are both 32 and 64 bit. + +|ios.release.distributionMethod +|string +|_(none)_ +|_(none)_ +|Specifies distribution type for release iOS builds only. This is used for enterprise or ad-hoc builds (using values "enterprise" and "ad-hoc" respectively). + +|ios.release.teamId +|string +|_(none)_ +|_(none)_ +|Specifies the team ID associated with the iOS release provisioning profile and certificate. + +|ios.rpmalloc +|string +|_(none)_ +|_(none)_ +|`true`/`false` Use https://github.com/rampantpixels/rpmalloc[rpmalloc] instead of malloc/free for memory allocation in ParparVM. This will cause the deployment target to be changed to a minimum of iOS 8.0. + +|ios.shareAppGroup +|string +|_(none)_ +|_(none)_ +| + +|ios.spm.packages +|list (`;` delimited) +|_(none)_ +|`@Ios(spmPackages)` +|Swift Package Manager packages to link, one per entry, each written as identity|url|requirement. + +|ios.spm.products.* +|string +|_(none)_ +|_(properties file only)_ +|Selects which products of a Swift Package Manager package to link, keyed by package identity. + +|ios.statusBarFG +|string +|_(none)_ +|_(none)_ +| + +|ios.statusbar_hidden +|boolean +|_(none)_ +|_(none)_ +|true/false defaults to false. Hides the iOS status bar if set to true. + +|ios.superfastBuild +|boolean +|`false` +|_(none)_ +| + +|ios.surfaces.appGroup +|string +|_(none)_ +|_(none)_ +| + +|ios.surfaces.buildSettings.* +|string +|_(none)_ +|_(properties file only)_ +|Overrides an Xcode build setting for the external-surfaces extension. + +|ios.surfaces.deploymentTarget +|version +|`16.1` +|_(none)_ +| + +|ios.surfaces.extension +|boolean +|`true` +|_(none)_ +| + +|ios.surfaces.frequentUpdates +|boolean +|`false` +|_(none)_ +| + +|ios.swiftVersion +|version +|`5.0` +|_(none)_ +| + +|ios.teamId +|string +|_(none)_ +|`@Ios(teamId)` +|Specifies the team ID associated with the iOS provisioning profile and certificate. Use `ios.debug.teamId` and `ios.release.teamId` to specify different team IDs for debug and release builds respectively. + +|ios.testFlight +|boolean +|_(none)_ +|_(none)_ +|Boolean true/false defaults to false and works only for pro accounts. Enables the testflight support in the release binaries for easy beta testing. Notice that the IDE plugin has a "Test Flight" check box you *should* use under the iOS section. + +|ios.themeMode +|`auto`, `modern`, `ios7`, `legacy` +|_(none)_ +|`@Ios(themeMode)` +|`auto` (default), `modern`, `ios7`, `legacy`. `auto` (unset) keeps the existing iOS 7 flat theme so pre-refactor screenshot goldens and apps see no behavior change. `modern` / `liquid` opts in to the CSS-generated iOS Modern (liquid-glass) theme shipped from `native-themes/ios-modern/theme.css`. `ios7` / `flat` is the same as `auto` - pre-liquid iOS 7 flat theme; `legacy` / `iphone` loads the pre-iOS 7 iPhone theme. The `auto` -> modern flip is planned for a future release. + +|ios.timeSensitiveNotifications +|boolean +|`false` +|_(none)_ +| + +|ios.twoDigitVersion +|boolean +|`false` +|_(none)_ +| + +|ios.uiscene +|boolean +|`true` +|`@Ios(uiscene)` +|true/false (defaults to true). Enables iOS UIScene lifecycle support. UIScene lets iOS manage one or more app UI sessions independently, improving lifecycle handling in modern iOS versions. Apple has indicated UIScene will be required starting with iOS 27, so this is now on by default; set the flag to `false` only if you need to temporarily fall back to the legacy `UIApplicationDelegate` lifecycle. + +|ios.urlScheme +|string +|_(none)_ +|`@Ios(urlScheme)` +|Allows intercepting a URL call using the syntax `urlPrefix` + +|ios.urlSchemes +|string +|_(none)_ +|_(none)_ +| + +|ios.useAVKit +|boolean +|`true` +|_(none)_ +|Use AVKit for video components on iOS rather than `MPMoviePlayerController` on iOS versions 8 through 12. iOS 13 will always use AVKit, and iOS 7 and lower will always use `MPMoviePlayerController`. Default value `false` + +|ios.useJavascriptCore +|boolean +|`false` +|_(none)_ +| + +|ios.usePhotoKitForMultigallery +|boolean +|`false` +|_(none)_ +| + +|ios.usePrintf +|boolean +|`false` +|_(none)_ +| + +|ios.useWKWebView +|boolean +|`true` +|_(none)_ +| + +|ios.usesBackgroundProcessing +|boolean +|`false` +|_(none)_ +| + +|ios.viewDidLoad +|string +|_(none)_ +|_(none)_ +|Objective-C code that can be injected into the iOS callback method (message) `viewDidLoad` + +|ios.viewDidLoadInclude +|string +|_(none)_ +|_(none)_ +| + +|ios.wallet.appGroup +|string +|_(none)_ +|_(none)_ +|App Group id starting with `group.` shared by the app and the generated Wallet extensions. The app publishes pass entries into this group through `com.codename1.payment.WalletExtension` and the group is added to the app and extension entitlements automatically. Required when `ios.wallet.extension=true`. + +|ios.wallet.authEndpoint +|string +|_(none)_ +|_(none)_ +|HTTPS URL the generated login UI extension POSTs `{"username","password"}` to; the JSON response's `token` is stored in the App Group for the provisioning request. Required when `ios.wallet.includeUI=true`. + +|ios.wallet.extension +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Generates an Apple Wallet issuer provisioning extension (the "From apps on your iPhone" flow in the Wallet app) and embeds it in the build. Requires `ios.wallet.appGroup` and `ios.wallet.issuerEndpoint`. See the Apple Wallet Extension chapter. + +|ios.wallet.includeUI +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Also generates the Wallet authorization UI extension - a login form shown inside the Wallet app when the app reports that authentication is required. Requires `ios.wallet.authEndpoint`. + +|ios.wallet.issuerEndpoint +|string +|_(none)_ +|_(none)_ +|HTTPS URL of the issuer backend endpoint that produces the encrypted provisioning payload. The generated extension POSTs Apple's certificates/nonce plus the card identifier and auth token there as JSON. Required when `ios.wallet.extension=true`. + +|ios.wallet.nonuiExtensionName +|string +|`WalletNonUIExtension` +|_(none)_ +| + +|ios.wallet.uiExtensionName +|string +|`WalletUIExtension` +|_(none)_ +| + +|ios.xcode_version +|string +|_(none)_ +|_(none)_ +|The version of Xcode used on the server. Defaults to 4.5; accepts 5.0 as an option and nothing else. + +|ios.zbar_flash +|boolean +|`true` +|_(none)_ +| + +|javascript.includeVideoJS +|boolean +|`false` +|_(none)_ +| + +|javascript.inject.afterHead +|string +|_(none)_ +|_(none)_ +|Content to be injected into the index.html file at the end of the `` tag. + +|javascript.inject.beforeHead +|string +|_(none)_ +|_(none)_ +|Content to be injected into the index.html file at the beginning of the `` tag. + +|javascript.inject_proxy +|boolean +|`true` +|_(none)_ +|true/false (defaults to `true`). The ParparVM builder generates a same-origin proxy bundle and configures the app to use it. Setting this to `false` disables both proxy generation and proxy URL injection. + +|javascript.minifying +|boolean +|_(none)_ +|_(none)_ +|true/false (defaults to `true`). By default the JavaScript code is minified to reduce file size. You may optionally disable minification by setting `javascript.minifying` to `false`. + +|javascript.port +|string +|_(none)_ +|_(none)_ +|`parparvm` (default) or `teavm`. Selects the public JavaScript compiler for cloud builds. `teavm` retains the original builder as a compatibility fallback. + +|javascript.portSources +|string +|_(none)_ +|_(none)_ +| + +|javascript.proxy.allowedTargets +|string +|_(none)_ +|_(none)_ +|Comma-separated target origins, host names, or wildcard subdomains that a generated proxy may access, for example `https://api.example.com,*.services.example.org`. If omitted, the proxy accepts any HTTP or HTTPS target and the build emits a warning. + +|javascript.proxy.target +|string +|`jakarta-servlet` +|_(none)_ +|The generated ParparVM proxy deployment platform. Supported values are `jakarta-servlet` (default), `javax-servlet`, `node`, `php`, `aws-lambda`, `google-cloud-functions`, `cloudflare-workers`, and `none`. + +|javascript.proxy.url +|string +|_(none)_ +|_(none)_ +|The URL of an existing proxy to use for network requests. Setting it suppresses generated proxy packaging unless `javascript.proxy.target` is also set. If `javascript.inject_proxy` is `false`, this build hint is ignored. + +|javascript.sourceFilesCopied +|boolean +|_(none)_ +|_(none)_ +|true/false (defaults to `false`). Setting this flag to `true` will cause available java source files to be included in the resulting .zip and .war files. These may be used by Chrome during debugging. + +|javascript.stopOnErrors +|boolean +|_(none)_ +|_(none)_ +|true/false (defaults to `true`). Causes a TeaVM JavaScript build to fail when the compiler reports warnings. Setting this to `false` may allow the fallback builder to complete, but can turn compiler diagnostics into runtime failures that are more difficult to debug. + +|javascript.teavm.version +|string +|_(none)_ +|_(none)_ +|(Optional) The version of TeaVM to use for the build. *Use caution*, only use this property if you know what you're doing! + +|linux.arch +|string +|_(none)_ +|_(none)_ +| + +|linux.cc +|string +|_(none)_ +|_(none)_ +| + +|linux.debug +|boolean +|`false` +|_(none)_ +| + +|linux.libc +|string +|`glibc` +|_(none)_ +| + +|linux.musl +|boolean +|`false` +|_(none)_ +| + +|linux.muslNativeCc +|boolean +|`false` +|_(none)_ +| + +|linux.toolchain +|string +|_(none)_ +|_(none)_ +| + +|desktop.mac.cef +|boolean +|_(none)_ +|_(none)_ +|Whetherto use CEF for media or BrowserComponent instead of JavaFX in Mac desktop builds. true/false. Default value is `false` (Jan 2021), but this will be changed to `true` in a future version. + +|macNative.appCategory +|string +|`public.app-category.utilities` +|_(none)_ +|Mac Native builds only. `LSApplicationCategoryType` in the generated Info.plist. Default `public.app-category.utilities`. See https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype[Apple's category list]. + +|macNative.bundleId +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. Used only when `macNative.deriveBundleId=false`. Default: `.mac`. + +|macNative.copyright +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. `NSHumanReadableCopyright` in the Info.plist. Defaults to `Copyright (c) `. + +|macNative.deriveBundleId +|boolean +|`true` +|_(none)_ +|Mac Native builds only. `true` (default) maps to Xcode's `DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER=YES` (Xcode appends `.maccatalyst` to the iOS bundle ID). Set to `false` to take the bundle ID verbatim from `macNative.bundleId`. + +|macNative.distribution +|string +|`appStore` +|_(none)_ +|Mac Native builds only. `appStore` (default), `developerID`, or `both`. Selects which entitlements + ExportOptions plist + signing certificate to emit. `both` emits parallel `*-AppStore.entitlements` / `*-DeveloperID.entitlements` and matching `ExportOptions-*-Mac.plist` files so a single project can be archived to either channel. + +|macNative.enabled +|boolean +|`false` +|_(none)_ +| + +|macNative.entitlements.allowJit +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. `true` enables `com.apple.security.cs.allow-jit` for hardened runtime. ParparVM is AOT-compiled so this is `false` by default; flip when bundling a JIT-using cn1lib. + +|macNative.entitlements.appSandbox +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. `true` enables `com.apple.security.app-sandbox`. Default is `true` for the `appStore` channel (Mac App Store requires the sandbox), `false` for `developerID`. + +|macNative.entitlements.extra +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. Free-form XML inserted verbatim inside the `…` of the generated entitlements plist. Use for entitlements Codename One doesn't expose individually. + +|macNative.entitlements.files.userSelected +|string +|`readwrite` +|_(none)_ +|Mac Native builds only. `readwrite` (default), `readonly`, or `none`. Sets the matching `com.apple.security.files.user-selected.*` entitlement. + +|macNative.entitlements.hardenedRuntime +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. `true` enables hardened runtime restrictions. Default is `true` for `developerID` (notarization requires it), `false` for `appStore`. + +|macNative.entitlements.network.client +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. Toggles `com.apple.security.network.client`. Default `true`. + +|macNative.entitlements.network.server +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. Toggles `com.apple.security.network.server`. Default `false`. + +|macNative.fixedWindowSize +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. Opt-in. Format `x` — for example `1024x685`. When set, the Catalyst window's `UISceneSession.sizeRestrictions` minimum and maximum are pinned to the requested size so every launch produces a byte-identical window. Default unset, in which case the window is resizable. The CI screenshot pipeline turns this on to keep the strict-pixel golden comparison stable; production apps should leave it off. + +|macNative.iosMinDeploymentTarget +|version +|`13.1` +|_(none)_ +|Mac Native builds only. iOS deployment-target floor for the Catalyst slice (`IPHONEOS_DEPLOYMENT_TARGET`). Default `13.1`. The plugin coerces the iOS slice's minimum upward when set. + +|macNative.minDeploymentTarget +|version +|`10.15` +|_(none)_ +|Mac Native builds only. Minimum macOS version (`MACOSX_DEPLOYMENT_TARGET`). Default `10.15` — earlier versions don't support Mac Catalyst. + +|macNative.notarize +|boolean +|`false` +|_(none)_ +| + +|macNative.notarize.appleId +|string +|_(none)_ +|_(none)_ +| + +|macNative.notarize.keychainProfile +|string +|_(none)_ +|_(none)_ +| + +|macNative.notarize.password +|string +|_(none)_ +|_(none)_ +| + +|macNative.notarize.teamId +|string +|_(none)_ +|_(none)_ +| + +|macNative.provisioningProfile.* +|string +|_(none)_ +|_(properties file only)_ +|Per-profile provisioning data for a native macOS build, keyed by profile name. + +|macNative.provisioningProfile.appStore +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. Provisioning profile name for App Store distribution — used only when `macNative.signing.style=manual`. + +|macNative.provisioningProfile.developerID +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. Provisioning profile name for Developer ID distribution — used only when `macNative.signing.style=manual`. + +|macNative.signing.style +|string +|`automatic` +|_(none)_ +|Mac Native builds only. `automatic` (default) lets Xcode pick the signing certificate; `manual` forces the certificate identity hints below to be respected verbatim. + +|macNative.signingIdentity.appStore +|string +|`Apple Distribution` +|_(none)_ +|Mac Native builds only. Signing certificate identity for the App Store channel. Default `Apple Distribution`. + +|macNative.signingIdentity.developerID +|string +|`Developer ID Application` +|_(none)_ +|Mac Native builds only. Signing certificate identity for the Developer ID channel. Default `Developer ID Application`. + +|macNative.teamId +|string +|_(none)_ +|_(none)_ +|Mac Native builds only. Apple Developer Team ID (alphanumeric). Falls back to `ios.release.teamId` → `ios.teamId` → `ios.debug.teamId` since most apps share a single Apple Developer Team for iOS and Mac. + +|tvNative.bundleId +|string +|_(none)_ +|_(none)_ +|Bundle identifier of the tvOS app. Defaults to `.tvos`. + +|tvNative.displayName +|string +|_(none)_ +|_(none)_ +|The tvOS app name shown on Apple TV. Defaults to the app's display name. + +|tvNative.enabled +|boolean +|`false` +|_(none)_ +|true/false (defaults to false). Adds an Apple TV (tvOS) application target to the iOS build. The tvOS app is a separate `appletvos` target built from the same Java/Kotlin sources through ParparVM (UIKit + Metal; tvOS has no OpenGL ES). Enabling it doesn't change the iOS app -- in particular it doesn't override the iOS app's `ios.metal` setting. Also turned on implicitly by `codename1.tvMain`. + +|tvNative.mainClass +|string +|_(none)_ +|_(none)_ +| + +|tvNative.minDeploymentTarget +|version +|`13.0` +|_(none)_ +|`TVOS_DEPLOYMENT_TARGET` for the tvOS target. Defaults to `13.0`. + +|tvNative.teamId +|string +|_(none)_ +|_(none)_ +|Apple Developer Team ID used to sign the tvOS target. Falls back to the iOS team id (`ios.release.teamId` / `ios.teamId` / `ios.debug.teamId`). + +|watchNative.enabled +|boolean +|`false` +|_(none)_ +| + +|watchNative.health +|string +|_(none)_ +|_(none)_ +| + +|watchNative.health.workoutProcessing +|boolean +|`false` +|_(none)_ +| + +|watchNative.mainClass +|string +|_(none)_ +|_(none)_ +| + +|win.desktop-vm +|string +|_(none)_ +|_(none)_ +|The JVM that should be bundled in the Windows desktop build. Windows desktop builds only. Supported values: zulu8, zuluFx8, zulu8-32bit, zuluFx8-32bit, zulu11, zuluFx11, zulu11-32bit, zuluFx11-32bit + +|win.installDirName +|string +|_(none)_ +|_(none)_ +|Windows desktop builds only. Overrides the default installation folder name suggested by the installer (under `Program Files`). Defaults to the application's main class name for backward compatibility. Use this build hint to set a user-friendly installation folder name (for example, `win.installDirName=My Application`). The application ID used by Windows for upgrade detection is unaffected, so existing installations continue to upgrade. + +|win.shortcutName +|string +|_(none)_ +|_(none)_ +|Windows desktop builds only. Overrides the name used for the Start Menu shortcut, the Desktop shortcut and (when `win.launchOnStart=true`) the autostart shortcut. Defaults to the application's main class name for backward compatibility. Use this build hint to set a user-friendly shortcut label (for example, `win.shortcutName=My Application`). + +|win.vm32bit +|boolean +|_(none)_ +|_(none)_ +|true/false (defaults to false). Forces windows desktop builds to use the Win32 JVM instead of the 64 bit VM making them compatible with older Windows Machines. This is off by default at the moment because of a bug in JDK 8 update 112 that might cause this to fail for some cases + +|windows.arch +|string +|_(none)_ +|_(none)_ +|Native Windows port only (the `windows-native` build target -- not the JVM `win.*` desktop hints above). Target CPU architecture for the standalone `.exe`: `x64` (the default) or `arm64`. Accepts the usual synonyms (`x86_64`/`amd64`, `aarch64`). clang-cl cross-compiles to the chosen architecture from either host. See the link:#_working_with_the_native_windows_port[Working with the native Windows port chapter]. + +|windows.calendar.restrictedCapability +|boolean +|`false` +|_(none)_ +| + +|windows.debug +|boolean +|`false` +|_(none)_ +|Native Windows port only. true/false (defaults to false). When `false` the `.exe` is built optimized and *stripped* -- no PDB, dead-stripped unreferenced code (`/OPT:REF`) and folded identical functions (`/OPT:ICF`) -- which is the shipping default. Set `true` to keep debug symbols (a `.pdb` next to the exe, via `RelWithDebInfo` / clang-cl `/Zi` + linker `/DEBUG`) so a native crash address can be symbolized during development. Optimizations stay on in both cases. + +|windows.extensions +|string +|_(none)_ +|_(none)_ +|Historical build hint for the discontinued UWP target. It's retained here only for legacy reference and isn't used by current supported build targets. + +|windows.msix +|boolean +|`false` +|_(none)_ +| + +|windows.msix.identityName +|string +|_(none)_ +|_(none)_ +| + +|windows.msix.password +|string +|_(none)_ +|_(none)_ +| + +|windows.msix.pfx +|string +|_(none)_ +|_(none)_ +| + +|windows.msix.publisher +|string +|_(none)_ +|_(none)_ +| + +|windows.msix.version +|string +|_(none)_ +|_(none)_ +| + +|windows.sdkRoot +|string +|_(none)_ +|_(none)_ +|Native Windows port only; used when building on a *non-Windows* host (for example a Linux build server). Path to a Windows SDK laid out by https://github.com/Jake-Shadle/xwin[`xwin splat`] (a directory containing `crt/include` and `sdk/include/um`), used to cross-compile the `.exe` with clang-cl + lld-link instead of a Visual Studio environment. If unset, the `CN1_XWIN_SYSROOT` environment variable is used. Ignored on Windows hosts, which build through Visual Studio. The same SDK serves both `windows.arch` targets (its `x86_64` / `aarch64` lib subdirs). + +|windows.signing +|boolean +|`true` +|_(none)_ +|Native Windows port only. `true`/`false` (default `true`). Set `false` to force an unsigned build even when a certificate is available. + +|windows.signing.digest +|string +|`sha256` +|_(none)_ +|Native Windows port only. Signature digest algorithm. Default `sha256`. + +|windows.signing.name +|string +|_(none)_ +|_(none)_ +| + +|windows.signing.password +|string +|_(none)_ +|_(none)_ +| + +|windows.signing.pkcs12 +|string +|_(none)_ +|_(none)_ +| + +|windows.signing.timestampUrl +|string +|`http://timestamp.digicert.com` +|_(none)_ +|Native Windows port only. RFC 3161 timestamp server used when signing, so the signature stays valid after the certificate expires. Default `http://timestamp.digicert.com`; set empty to disable timestamping. + +|windows.signing.url +|string +|_(none)_ +|_(none)_ +| + +|=== diff --git a/maven/build-hint-catalog/pom.xml b/maven/build-hint-catalog/pom.xml new file mode 100644 index 00000000000..24045b96c83 --- /dev/null +++ b/maven/build-hint-catalog/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + com.codenameone + codenameone + 8.0-SNAPSHOT + + codenameone-build-hint-catalog + Codename One Build Hint Catalog + Shared registry describing every Codename One build hint: type, default, value domain and merge semantics + + 1.8 + 1.8 + UTF-8 + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + diff --git a/maven/cn1app-archetype/src/main/resources/archetype-resources/common/codenameone_settings.properties b/maven/cn1app-archetype/src/main/resources/archetype-resources/common/codenameone_settings.properties index 8f0bf0d6d5e..33d9b8ef65d 100644 --- a/maven/cn1app-archetype/src/main/resources/archetype-resources/common/codenameone_settings.properties +++ b/maven/cn1app-archetype/src/main/resources/archetype-resources/common/codenameone_settings.properties @@ -4,17 +4,14 @@ codename1.android.keystore= codename1.android.keystoreAlias= codename1.android.keystorePassword= -codename1.arg.ios.newStorageLocation=true -# Modern native themes (iOS liquid-glass + Material 3) - opt-in. -codename1.arg.nativeTheme=modern -codename1.arg.ios.themeMode=modern -codename1.arg.and.themeMode=modern -# Desktop integration (only takes effect when the app runs on the desktop). titleBar mode is -# one of: native (OS title bar + native menu bar), custom (undecorated, CN1-drawn title bar) or -# toolbar (legacy in-app CN1 Toolbar). interactiveScrollbars enables grab-able, click-to-page -# desktop scrollbars. These are honored by the generated desktop Stub. -codename1.arg.desktop.titleBar=native -codename1.arg.desktop.interactiveScrollbars=true +# Build hints are now declared as annotations on the main class, where the +# compiler checks them -- see the @Ios / @Android / @Desktop / @Build +# annotations on ${mainName}. Setting the same hint here as well is a build +# error, so move a hint rather than copying it. +# +# java.version stays here on purpose: it selects the toolchain that compiles +# the very class the annotations live on, and the project generator resolves it +# before any code is compiled. codename1.arg.java.version=${javaVersion} codename1.displayName=${mainName} codename1.icon=icon.png @@ -35,6 +32,11 @@ codename1.ios.release.provision= # See the "On-Device Debugging (iOS)" chapter of the developer guide # for the full setup (the IntelliJ Run/Debug configs that come with # this project's .idea/ directory are wired against these hints). +# +# These have a checked form too. On the main class: +# @OnDeviceDebug(ios = true, iosProxyHost = "127.0.0.1", iosProxyPort = 55333) +# and iosWaitForAttach = true to block at boot until the debugger attaches. +# Use one form or the other -- declaring a hint in both places fails the build. #codename1.arg.ios.onDeviceDebug=true #codename1.arg.ios.onDeviceDebug.proxyHost=127.0.0.1 #codename1.arg.ios.onDeviceDebug.proxyPort=55333 @@ -47,7 +49,8 @@ codename1.ios.release.provision= # bundled with this project, or with the cn1:android-on-device-debugging # Maven goal. See the "On-Device Debugging (Android)" chapter of the # developer guide for the wireless-debugging instructions and the full -# adb flow. +# adb flow. The checked form is @OnDeviceDebug(android = true) on the +# main class; use one form or the other, not both. #codename1.arg.android.onDeviceDebug=true codename1.j2me.nativeTheme=nbproject/nativej2me.res codename1.kotlin=false diff --git a/maven/cn1app-archetype/src/main/resources/archetype-resources/common/src/main/java/__mainName__.java b/maven/cn1app-archetype/src/main/resources/archetype-resources/common/src/main/java/__mainName__.java index a415a02bd87..44d6a1a1b39 100644 --- a/maven/cn1app-archetype/src/main/resources/archetype-resources/common/src/main/java/__mainName__.java +++ b/maven/cn1app-archetype/src/main/resources/archetype-resources/common/src/main/java/__mainName__.java @@ -4,6 +4,7 @@ package ${package}; import static com.codename1.ui.CN.*; +import com.codename1.annotations.buildhints.*; import com.codename1.system.Lifecycle; import com.codename1.ui.*; import com.codename1.ui.layouts.*; @@ -14,7 +15,19 @@ /** * This file was generated by Codename One for the purpose * of building native mobile applications using Java. + * + *

The annotations below are build hints: settings the native build reads, + * written so the compiler checks them. A misspelled name is an unknown symbol + * and an unsupported value is an unknown enum constant, rather than a line in + * codenameone_settings.properties that is silently ignored. Hints that have no + * annotation yet, and open-ended ones such as android.permission.<NAME>, + * still go in that file; setting the same hint in both places is a build + * error.

*/ +@Ios(newStorageLocation = true, themeMode = IosThemeMode.MODERN) +@Android(themeMode = AndroidThemeMode.MODERN) +@Desktop(titleBar = DesktopTitleBar.NATIVE, interactiveScrollbars = true) +@Build(nativeTheme = NativeThemeMode.MODERN) public class ${mainName} extends Lifecycle { @Override public void runApp() { diff --git a/maven/codenameone-maven-plugin/pom.xml b/maven/codenameone-maven-plugin/pom.xml index aff7d0c4312..1a048926888 100644 --- a/maven/codenameone-maven-plugin/pom.xml +++ b/maven/codenameone-maven-plugin/pom.xml @@ -39,6 +39,11 @@ codenameone-platform-feature-catalog ${project.version} + + ${project.groupId} + codenameone-build-hint-catalog + ${project.version} + org.jdom jdom2 diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java index df9c6698b1e..8c01a5432f7 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java @@ -1481,6 +1481,13 @@ private void createAntProject() throws IOException, LibraryPropertiesException, try (FileInputStream fis = new FileInputStream(codenameOneSettingsCopy)) { cn1SettingsProps.load(fis); } + // Build hints declared as annotations on the main class. Merged here, before + // everything that consumes the effective configuration: the command-line + // overlay below (so -D still wins), the CN1Lib appended/required merges (so a + // library appends onto an annotation-supplied value exactly as it would onto a + // file-supplied one), the gradle sanity check, both preflights, and the copy + // that is written back out and uploaded. + mergeAnnotationBuildHints(cn1SettingsProps, cpElements); // The build request is assembled from this copy, not from the mojo's // own properties, so the command-line overlay has to be applied here // too -- otherwise a hint passed with -D is read by the mojo and still @@ -2521,4 +2528,104 @@ private SortedProperties mergeRequiredProperties(String libraryName, Properties return merged; } + + /** + * Name of the resource {@code BuildHintAnnotationProcessor} emits into + * {@code target/classes} at PROCESS_CLASSES. + */ + private static final String ANNOTATION_HINTS_RESOURCE = + "META-INF/codenameone/build-hints.properties"; + + /** + * Overlays the build hints that came from annotations onto the settings the + * build request is assembled from. + * + *

Read from the compile classpath rather than from the staged fat jar. + * {@code mergeJars} builds that jar with Ant's {@code Zip} in update mode, + * which adds and overwrites entries but never removes one, and the jar is + * reused when it is not stale — so a project that had its annotations + * deleted would keep shipping yesterday's hints. The classpath directory is + * written by the annotation processor on every build and deleted by it when + * the last annotation goes away, so it always reflects the current source.

+ */ + private void mergeAnnotationBuildHints(Properties target, List classpathElements) { + if (target == null || classpathElements == null) { + return; + } + String expectedMain = null; + if (properties != null) { + String main = properties.getProperty("codename1.mainName"); + String pkg = properties.getProperty("codename1.packageName"); + if (main != null && main.trim().length() > 0) { + expectedMain = (pkg == null || pkg.trim().length() == 0) + ? main.trim() : pkg.trim() + "." + main.trim(); + } + } + for (String element : classpathElements) { + Properties found = readAnnotationHints(new File(element)); + if (found == null) { + continue; + } + String stamped = found.getProperty("cn1.buildHints.mainClass"); + if (expectedMain != null && stamped != null && !expectedMain.equals(stamped)) { + // A cn1lib that bound the goal itself, or a stale artifact. Merging it + // would apply another project's build configuration to this one. + getLog().debug("cn1: ignoring build hints from " + element + + " -- they were generated for " + stamped); + continue; + } + int applied = 0; + for (String key : found.stringPropertyNames()) { + if (!key.startsWith("codename1.arg.")) { + continue; + } + target.setProperty(key, found.getProperty(key)); + applied++; + } + if (applied > 0) { + getLog().info("cn1: applied " + applied + " build hint(s) from annotations"); + return; + } + } + } + + /** + * Reads the emitted hints out of a classpath element, which is either the + * module's output directory or a jar. + * + * @return the properties, or null when this element carries none + */ + private Properties readAnnotationHints(File element) { + if (element == null || !element.exists()) { + return null; + } + try { + if (element.isDirectory()) { + File f = new File(element, ANNOTATION_HINTS_RESOURCE); + if (!f.isFile()) { + return null; + } + try (FileInputStream in = new FileInputStream(f)) { + Properties p = new Properties(); + p.load(in); + return p; + } + } + try (java.util.zip.ZipFile zip = new java.util.zip.ZipFile(element)) { + java.util.zip.ZipEntry entry = zip.getEntry(ANNOTATION_HINTS_RESOURCE); + if (entry == null) { + return null; + } + try (InputStream in = zip.getInputStream(entry)) { + Properties p = new Properties(); + p.load(in); + return p; + } + } + } catch (IOException ex) { + getLog().warn("cn1: could not read build hints from " + element + ": " + + ex.getMessage()); + return null; + } + } } diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/LibraryHintMerger.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/LibraryHintMerger.java index afc9afa70fb..3649854a508 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/LibraryHintMerger.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/LibraryHintMerger.java @@ -22,8 +22,8 @@ */ package com.codename1.maven; -import java.util.HashMap; -import java.util.Map; +import com.codename1.build.shared.BuildHints; + import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -56,46 +56,6 @@ public class LibraryHintMerger { /** Prefix every build hint carries inside a settings/library properties file. */ private static final String ARG_PREFIX = "codename1.arg."; - /** - * Separator per hint, keyed by the name with {@link #ARG_PREFIX} stripped. - * - *

Read off how the builders themselves split or append each value, not invented here: - * {@code IPhoneBuilder} splits {@code ios.pods} and {@code ios.applicationQueriesSchemes} - * on {@code ","} and joins {@code ios.add_libs} with {@code ";"}, while every - * {@code AndroidGradleBuilder} injection into a Gradle text hint appends a newline-wrapped - * statement. A hint absent from this map keeps the historical bare concatenation, which is - * what the XML-fragment hints want.

- */ - private static final Map SEPARATORS = new HashMap(); - static { - // A Gradle dependency list. ';' rather than a newline because this is the hint - // users hand-edit most, every existing project and cn1lib already writes it that - // way, and keeping the value on one line survives any line-oriented tooling that - // rewrites codenameone_settings.properties. - SEPARATORS.put("android.gradleDep", ";"); - // Block structured Gradle text, where a statement per line is the only thing that - // reads correctly -- and what our own builder injections already append. - SEPARATORS.put("gradleDependencies", "\n"); - SEPARATORS.put("android.topDependency", "\n"); - SEPARATORS.put("android.repositories", "\n"); - SEPARATORS.put("android.xgradle", "\n"); - SEPARATORS.put("android.gradle.androidx", "\n"); - SEPARATORS.put("android.xgradle_default_config", "\n"); - SEPARATORS.put("android.gradlePlugin", "\n"); - SEPARATORS.put("android.supportv4Dep", "\n"); - // ProGuard/R8 directives are line oriented. - SEPARATORS.put("android.proguardKeep", "\n"); - // Comma-delimited lists. - SEPARATORS.put("ios.pods", ","); - SEPARATORS.put("ios.applicationQueriesSchemes", ","); - // Semicolon-delimited lists. - SEPARATORS.put("ios.add_libs", ";"); - // Attributes spliced into a single XML tag, so they abut with a space rather than - // directly -- android:allowBackup="false"android:hardwareAccelerated="true" is not - // a well formed tag. - SEPARATORS.put("android.xapplication_attr", " "); - } - private LibraryHintMerger() { } @@ -103,6 +63,10 @@ private LibraryHintMerger() { * The separator two values of this hint must be joined with, or an empty string when the * hint's values abut directly (the XML-fragment hints). * + *

The table lives in {@link BuildHints}, which is also what the build hint annotations + * are generated from. Keeping one copy is what stops a {@code String[]} attribute being + * joined with one delimiter here and split with another by the builder.

+ * * @param propertyName hint name, with or without the {@code codename1.arg.} prefix * @return the separator, never null */ @@ -113,8 +77,7 @@ public static String separatorFor(String propertyName) { String name = propertyName.startsWith(ARG_PREFIX) ? propertyName.substring(ARG_PREFIX.length()) : propertyName; - String separator = SEPARATORS.get(name); - return separator == null ? "" : separator; + return BuildHints.separatorFor(name); } /** diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java new file mode 100644 index 00000000000..a9f7ab5280e --- /dev/null +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -0,0 +1,505 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.maven; + +import com.codename1.build.shared.BuildHints; +import com.codename1.build.shared.HintType; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; + +/** + * Rewrites {@code codename1.arg.*} lines in {@code codenameone_settings.properties} + * as build hint annotations on the application's main class. + * + *

A build hint written as a properties line is a string nothing checks: a + * misspelled name is accepted, never read, and silently does nothing. The same + * hint written as an annotation is checked by the compiler. This goal moves the + * ones that have an annotation and leaves the rest alone.

+ * + *

Runs in place and prints what it did. Pass {@code -Dcn1.migrate.dryRun=true} + * to see the plan without touching anything.

+ */ +// Aggregator: every module of a Codename One project resolves to the same +// codenameone_settings.properties, so running per-module would try to migrate +// the same file several times and the second pass would find its own output. +@Mojo(name = "migrate-build-hints", requiresProject = true, aggregator = true, + requiresDependencyResolution = ResolutionScope.COMPILE) +public class MigrateBuildHintsMojo extends AbstractCN1Mojo { + + /** + * The whole reactor. This goal is an aggregator, so {@code project} is the + * root pom -- which carries no codenameone-core dependency of its own. The + * core has to be looked for across the modules. + */ + @Parameter(defaultValue = "${session.projects}", readonly = true, required = true) + private java.util.List reactorProjects; + + /** Report what would change without writing anything. */ + @Parameter(property = "cn1.migrate.dryRun", defaultValue = "false") + private boolean dryRun; + + /** + * Hints to leave in the properties file even though they have an annotation. + * {@code java.version} is always kept: it selects the toolchain that compiles + * the class the annotations would live on, so it has to be readable before + * any of the project's own code exists. + */ + @Parameter(property = "cn1.migrate.keep") + private String keep; + + @Override + protected void executeImpl() throws MojoExecutionException, MojoFailureException { + File projectDir = getCN1ProjectDir(); + if (projectDir == null) { + throw new MojoExecutionException("No Codename One project directory found; " + + "this goal must run in a project with a codenameone_settings.properties."); + } + File settingsFile = new File(projectDir, "codenameone_settings.properties"); + if (!settingsFile.isFile()) { + throw new MojoExecutionException("No codenameone_settings.properties in " + projectDir); + } + + // The annotations ship in codenameone-core. A project pinned to a release + // that predates them would migrate cleanly here and then fail to compile, + // so refuse rather than hand back a broken project. + if (!coreHasBuildHintAnnotations()) { + throw new MojoFailureException("This project builds against a Codename One version " + + "whose core has no com.codename1.annotations.buildhints package, so the " + + "annotations would not resolve. Update the project's cn1.version first."); + } + + Properties settings = new Properties(); + try (FileInputStream in = new FileInputStream(settingsFile)) { + settings.load(in); + } catch (IOException ex) { + throw new MojoExecutionException("Could not read " + settingsFile, ex); + } + + List kept = new ArrayList(); + kept.add("java.version"); + if (keep != null) { + for (String k : keep.split(",")) { + if (k.trim().length() > 0) { + kept.add(k.trim()); + } + } + } + + // Resolve the target language before rendering: Kotlin writes an array + // literal as [a, b] and rejects Java's {a, b}, so the same hint renders + // differently depending on which file it is going into. + String mainSourcePath = findMainClassSource(projectDir, settings); + boolean kotlinTarget = mainSourcePath != null && mainSourcePath.endsWith(".kt"); + + // annotation simple name -> attribute -> source literal + Map> plan = new TreeMap>(); + List migratedKeys = new ArrayList(); + List skipped = new ArrayList(); + + for (String key : new ArrayList(settings.stringPropertyNames())) { + if (!key.startsWith(BuildHints.ARG_PREFIX)) { + continue; + } + String name = key.substring(BuildHints.ARG_PREFIX.length()); + if (kept.contains(name)) { + skipped.add(name + " (kept by configuration)"); + continue; + } + BuildHints.Hint hint = BuildHints.byName(name); + if (hint == null || !hint.isAnnotated()) { + skipped.add(name + " (no annotation for this hint yet)"); + continue; + } + String literal = toSourceLiteral(hint, settings.getProperty(key), kotlinTarget); + if (literal == null) { + skipped.add(name + " = '" + settings.getProperty(key) + + "' (value is outside the hint's supported set)"); + continue; + } + String annotation = hint.group().annotationSimpleName(); + Map members = plan.get(annotation); + if (members == null) { + members = new TreeMap(); + plan.put(annotation, members); + } + members.put(hint.attr(), literal); + migratedKeys.add(key); + } + + if (plan.isEmpty()) { + getLog().info("cn1: nothing to migrate -- no annotated build hint is set in " + + settingsFile.getName()); + for (String s : skipped) { + getLog().debug("cn1: left in place: " + s); + } + return; + } + + String mainSource = mainSourcePath; + StringBuilder rendered = new StringBuilder(); + for (Map.Entry> e : plan.entrySet()) { + rendered.append(render(e.getKey(), e.getValue())).append('\n'); + } + + getLog().info("cn1: move these onto " + (mainSource == null ? "your main class" + : new File(mainSource).getName()) + ":"); + for (String line : rendered.toString().split("\n")) { + getLog().info("cn1: " + line); + } + for (String s : skipped) { + getLog().info("cn1: leaving " + s); + } + + if (dryRun) { + getLog().info("cn1: dry run -- nothing written"); + return; + } + if (mainSource == null) { + throw new MojoFailureException("Could not find the source of the main class named by " + + "codename1.mainName. Add the annotations above by hand, then delete the " + + "migrated lines from " + settingsFile.getName() + "."); + } + + try { + insertAnnotations(new File(mainSource), rendered.toString(), + settings.getProperty("codename1.mainName", "").trim()); + removeMigratedLines(settingsFile, migratedKeys); + } catch (IOException ex) { + throw new MojoExecutionException("Migration failed: " + ex.getMessage(), ex); + } + getLog().info("cn1: migrated " + migratedKeys.size() + " build hint(s) into " + + new File(mainSource).getName()); + } + + /** + * Whether the codenameone-core on this project's compile classpath actually + * carries the annotations. + */ + private boolean coreHasBuildHintAnnotations() { + java.util.List projects = reactorProjects; + if (projects == null || projects.isEmpty()) { + projects = java.util.Collections.singletonList(project); + } + for (org.apache.maven.project.MavenProject p : projects) { + if (carriesBuildHintAnnotations(p)) { + return true; + } + } + return false; + } + + private boolean carriesBuildHintAnnotations(org.apache.maven.project.MavenProject p) { + try { + for (Object element : p.getCompileClasspathElements()) { + File f = new File((String) element); + if (f.isDirectory()) { + if (new File(f, "com/codename1/annotations/buildhints/Ios.class").isFile()) { + return true; + } + } else if (f.isFile()) { + try (java.util.zip.ZipFile zip = new java.util.zip.ZipFile(f)) { + if (zip.getEntry("com/codename1/annotations/buildhints/Ios.class") != null) { + return true; + } + } + } + } + } catch (Exception ex) { + getLog().debug("cn1: could not inspect the compile classpath: " + ex.getMessage()); + return true; + } + return false; + } + + /** + * Renders a value as the Java literal for its attribute. + * + * @return the literal, or null when the value is outside a closed domain -- + * which is worth reporting rather than silently translating, because + * it means the properties file has been setting something the build + * never understood + */ + String toSourceLiteral(BuildHints.Hint hint, String value, boolean kotlin) { + if (value == null) { + return null; + } + String v = value.trim(); + switch (hint.type()) { + case BOOLEAN: + if ("true".equalsIgnoreCase(v)) return "true"; + if ("false".equalsIgnoreCase(v)) return "false"; + return null; + case INT: + try { + return String.valueOf(Integer.parseInt(v)); + } catch (NumberFormatException ex) { + return null; + } + case ENUM: + for (String allowed : hint.values()) { + if (allowed.equalsIgnoreCase(v)) { + return hint.enumName() + "." + enumConstant(allowed); + } + } + return null; + case STRING_LIST: { + String sep = hint.separator(); + if (sep == null || sep.length() == 0) { + return quote(v); + } + String[] parts = v.split(java.util.regex.Pattern.quote(sep), -1); + StringBuilder sb = new StringBuilder(kotlin ? "[" : "{"); + int written = 0; + for (String part : parts) { + String t = part.trim(); + if (t.length() == 0) { + continue; + } + if (written++ > 0) { + sb.append(", "); + } + sb.append(quote(t)); + } + return sb.append(kotlin ? ']' : '}').toString(); + } + default: + return quote(v); + } + } + + /** Mirrors the generator's wire-value to constant-name mapping. */ + static String enumConstant(String wire) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < wire.length(); i++) { + char c = wire.charAt(i); + if (Character.isUpperCase(c) && sb.length() > 0 + && Character.isLowerCase(wire.charAt(i - 1))) { + sb.append('_'); + } + sb.append(Character.isLetterOrDigit(c) ? Character.toUpperCase(c) : '_'); + } + String out = sb.toString(); + return out.length() > 0 && Character.isDigit(out.charAt(0)) ? "V" + out : out; + } + + private static String quote(String s) { + StringBuilder sb = new StringBuilder("\""); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '"': sb.append("\\\""); break; + case '\\': sb.append("\\\\"); break; + case '\n': sb.append("\\n"); break; + case '\r': sb.append("\\r"); break; + case '\t': sb.append("\\t"); break; + default: sb.append(c); + } + } + return sb.append('"').toString(); + } + + static String render(String annotation, Map members) { + StringBuilder sb = new StringBuilder("@").append(annotation).append('('); + int i = 0; + for (Map.Entry e : members.entrySet()) { + if (i++ > 0) { + sb.append(", "); + } + sb.append(e.getKey()).append(" = ").append(e.getValue()); + } + return sb.append(')').toString(); + } + + private String findMainClassSource(File projectDir, Properties settings) { + String main = settings.getProperty("codename1.mainName"); + String pkg = settings.getProperty("codename1.packageName"); + if (main == null || main.trim().length() == 0) { + return null; + } + String path = (pkg == null ? "" : pkg.trim().replace('.', File.separatorChar) + + File.separator) + main.trim(); + String[] roots = {"src" + File.separator + "main" + File.separator + "java", + "src" + File.separator + "main" + File.separator + "kotlin", + "src"}; + String[] extensions = {".java", ".kt"}; + for (String root : roots) { + for (String ext : extensions) { + File f = new File(projectDir, root + File.separator + path + ext); + if (f.isFile()) { + return f.getAbsolutePath(); + } + } + } + return null; + } + + /** + * Splices the annotations in above the class declaration, with the import. + * + *

Textual rather than a parse: the file may be Java or Kotlin, it may use + * any formatting, and rewriting it through a parser would reformat code the + * developer did not ask to have touched.

+ */ + private void insertAnnotations(File source, String annotations, String simpleName) + throws IOException { + String text = read(source); + boolean kotlin = source.getName().endsWith(".kt"); + String importLine = kotlin + ? "import com.codename1.annotations.buildhints.*" + : "import com.codename1.annotations.buildhints.*;"; + if (text.contains("com.codename1.annotations.buildhints")) { + throw new IOException(source.getName() + " already imports the build hint " + + "annotations; migrate the remaining hints by hand so nothing is " + + "overwritten."); + } + + int declaration = classDeclarationIndex(text, kotlin, simpleName); + if (declaration < 0) { + throw new IOException("Could not find the class declaration in " + source.getName()); + } + String head = text.substring(0, declaration); + String tail = text.substring(declaration); + + int lastImport = head.lastIndexOf("\nimport "); + if (lastImport >= 0) { + int eol = head.indexOf('\n', lastImport + 1); + head = head.substring(0, eol + 1) + importLine + "\n" + head.substring(eol + 1); + } else { + int pkgEnd = head.indexOf('\n', head.indexOf("package ")); + head = head.substring(0, pkgEnd + 1) + "\n" + importLine + "\n" + + head.substring(pkgEnd + 1); + } + write(source, head + annotations + tail); + } + + /** + * Index of the start of the line declaring the top-level type. + * + *

Matched by pattern rather than against a list of prefixes: a declaration + * can carry any combination of modifiers -- {@code public final class}, + * {@code internal data class} -- and a missing combination would abort the + * migration on a perfectly ordinary file. Anchored to column zero so a + * nested type or a mention inside an indented doc comment cannot match, and + * the type named by {@code codename1.mainName} is preferred over whatever + * happens to appear first.

+ */ + static int classDeclarationIndex(String text, boolean kotlin, String simpleName) { + String modifiers = kotlin + ? "(?:public |internal |private |open |abstract |final |sealed |data |value |annotation )*" + : "(?:public |protected |private |abstract |final |static |strictfp |sealed |non-sealed )*"; + String kinds = kotlin ? "(?:class|object|interface)" : "(?:class|interface|enum|record)"; + java.util.regex.Pattern named = java.util.regex.Pattern.compile( + "(?m)^" + modifiers + kinds + "\\s+" + + java.util.regex.Pattern.quote(simpleName == null ? "" : simpleName) + + "\\b"); + java.util.regex.Matcher m = named.matcher(text); + if (simpleName != null && simpleName.length() > 0 && m.find()) { + return m.start(); + } + java.util.regex.Matcher any = java.util.regex.Pattern.compile( + "(?m)^" + modifiers + kinds + "\\s+\\w").matcher(text); + return any.find() ? any.start() : -1; + } + + /** + * Deletes the migrated lines, leaving every other line -- comments, + * ordering, unrelated settings -- byte for byte as it was. + */ + private void removeMigratedLines(File settingsFile, List keys) throws IOException { + List lines = new ArrayList(); + BufferedReader r = new BufferedReader( + new InputStreamReader(new FileInputStream(settingsFile), "ISO-8859-1")); + try { + String line; + while ((line = r.readLine()) != null) { + lines.add(line); + } + } finally { + r.close(); + } + Map wanted = new LinkedHashMap(); + for (String k : keys) { + wanted.put(k, Boolean.TRUE); + } + StringBuilder out = new StringBuilder(); + for (String line : lines) { + String t = line.trim(); + boolean drop = false; + if (t.length() > 0 && t.charAt(0) != '#' && t.charAt(0) != '!') { + int eq = t.indexOf('='); + int colon = t.indexOf(':'); + int split = eq < 0 ? colon : (colon < 0 ? eq : Math.min(eq, colon)); + if (split > 0 && wanted.containsKey(t.substring(0, split).trim())) { + drop = true; + } + } + if (!drop) { + out.append(line).append('\n'); + } + } + write(settingsFile, out.toString()); + } + + private static String read(File f) throws IOException { + StringBuilder sb = new StringBuilder(); + BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8")); + try { + int c; + while ((c = r.read()) >= 0) { + sb.append((char) c); + } + } finally { + r.close(); + } + return sb.toString(); + } + + private static void write(File f, String content) throws IOException { + Writer w = new OutputStreamWriter(new FileOutputStream(f), "UTF-8"); + try { + w.write(content); + } finally { + w.close(); + } + } +} diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/OpenSettingsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/OpenSettingsMojo.java index 3e8e426c683..f873958bda6 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/OpenSettingsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/OpenSettingsMojo.java @@ -231,13 +231,15 @@ File extractSettingsIcon(File jar, File runtimeDir) { void writeBinding(File inputFile, File projectDir) throws MojoExecutionException { File root = multimoduleRoot(projectDir); - File buildHints = new File(root, "docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc"); + // No buildHintsDoc: the Settings tool used to scrape the developer guide's + // AsciiDoc table at runtime and guess each hint's type from its description + // prose. It now reads com.codename1.build.shared.BuildHints, the same table + // the build hint annotations are generated from. String content = "# Codename One Settings project binding\n" + "projectDir=" + projectDir.getAbsolutePath() + "\n" + "settings=" + new File(projectDir, "codenameone_settings.properties").getAbsolutePath() + "\n" + "pom=" + new File(projectDir, "pom.xml").getAbsolutePath() + "\n" - + "multimoduleRoot=" + root.getAbsolutePath() + "\n" - + (buildHints.isFile() ? "buildHintsDoc=" + buildHints.getAbsolutePath() + "\n" : ""); + + "multimoduleRoot=" + root.getAbsolutePath() + "\n"; try { FileUtils.write(inputFile, content, StandardCharsets.UTF_8); } catch (IOException ex) { diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/ProcessAnnotationsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/ProcessAnnotationsMojo.java index c7829d15e5a..6d2cdb575b9 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/ProcessAnnotationsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/ProcessAnnotationsMojo.java @@ -35,13 +35,16 @@ import org.apache.maven.plugins.annotations.Parameter; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.ServiceLoader; import java.util.Set; @@ -103,7 +106,7 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException } ProcessorContext ctx = new ProcessorContext(outputDirectory, stubSourceDirectory, - index, getLog()); + index, getLog(), getCN1ProjectDir(), rawProjectSettings(), mainClassBinaryName()); // start() for (Iterator it = processors.iterator(); it.hasNext(); ) { @@ -238,4 +241,55 @@ private List loadProcessors() { for (AnnotationProcessor p : sl) out.add(p); return Collections.unmodifiableList(out); } + + /// Loads `codenameone_settings.properties` exactly as it sits on disk. + /// + /// Deliberately not the inherited `properties` field: that one has the + /// `-D` command line overlaid on top of it, and a hint passed with `-D` is + /// the documented way to override one for a single build. A processor that + /// compared annotations against the overlaid view would report a conflict + /// for the one case that is supposed to win. + private Properties rawProjectSettings() { + File f = getProjectPropertiesFile(); + if (f == null || !f.exists()) { + return null; + } + Properties p = new Properties(); + InputStream in = null; + try { + in = new FileInputStream(f); + p.load(in); + } catch (IOException ex) { + getLog().warn("cn1: could not read " + f + ": " + ex.getMessage()); + return null; + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException ignored) { + // nothing useful to do on close failure of a read-only stream + } + } + } + return p; + } + + /// `codename1.packageName` + `codename1.mainName`, or null when the project + /// declares no main class. + private String mainClassBinaryName() { + Properties p = rawProjectSettings(); + if (p == null) { + return null; + } + String main = p.getProperty("codename1.mainName"); + String pkg = p.getProperty("codename1.packageName"); + if (main == null || main.trim().length() == 0) { + return null; + } + main = main.trim(); + if (pkg == null || pkg.trim().length() == 0) { + return main; + } + return pkg.trim() + "." + main; + } } diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/annotations/ProcessorContext.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/annotations/ProcessorContext.java index 7eb35bec52a..254e85743b1 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/annotations/ProcessorContext.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/annotations/ProcessorContext.java @@ -28,6 +28,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Properties; import org.apache.maven.plugin.logging.Log; @@ -45,6 +46,9 @@ /// - A **stub source directory** in `target/generated-sources/cn1-annotations` /// used by the GENERATE_SOURCES Mojo; the PROCESS_CLASSES path doesn't write /// to it but the directory may exist either way. +/// - The **project settings** exactly as `codenameone_settings.properties` +/// holds them, plus the main class those settings name. A processor that +/// validates against project configuration needs both. public final class ProcessorContext { private final File outputClassDir; @@ -55,17 +59,48 @@ public final class ProcessorContext { private final Map emittedClasses = new LinkedHashMap(); private final Map emittedStubSources = new LinkedHashMap(); private final Map emittedResources = new LinkedHashMap(); + private final File projectDir; + private final Properties projectSettings; + private final String mainClassBinaryName; public ProcessorContext(File outputClassDir, File stubSourceDir, Map classIndex, Log log) { + this(outputClassDir, stubSourceDir, classIndex, log, null, null, null); + } + + /// Full form, adding the project configuration. + /// + /// `projectSettings` must be the **raw** contents of + /// `codenameone_settings.properties`, without any `-D` overlay: a hint given + /// on the command line is the documented way to override one for a single + /// build, so it must never be mistaken for something the project declares. + public ProcessorContext(File outputClassDir, File stubSourceDir, + Map classIndex, Log log, + File projectDir, Properties projectSettings, + String mainClassBinaryName) { this.outputClassDir = outputClassDir; this.stubSourceDir = stubSourceDir; this.classIndex = classIndex == null ? Collections.emptyMap() : Collections.unmodifiableMap(new LinkedHashMap(classIndex)); this.log = log; + this.projectDir = projectDir; + this.projectSettings = projectSettings; + this.mainClassBinaryName = mainClassBinaryName; } + /// The Codename One project directory -- the one holding + /// `codenameone_settings.properties` -- or null when it could not be found. + public File getProjectDir() { return projectDir; } + + /// The raw `codenameone_settings.properties`, or null when absent. Never + /// carries a `-D` overlay; see the constructor. + public Properties getProjectSettings() { return projectSettings; } + + /// Fully qualified name of the class named by `codename1.mainName`, or null + /// when the project does not declare one (a cn1lib, for instance). + public String getMainClassBinaryName() { return mainClassBinaryName; } + /// `target/classes` for the project, or the equivalent output directory. public File getOutputClassDir() { return outputClassDir; } diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/processors/BuildHintAnnotationProcessor.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/processors/BuildHintAnnotationProcessor.java new file mode 100644 index 00000000000..83bf3482f59 --- /dev/null +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/processors/BuildHintAnnotationProcessor.java @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.maven.processors; + +import com.codename1.build.shared.BuildHintAnnotationBinding; +import com.codename1.build.shared.BuildHints; +import com.codename1.maven.annotations.AbstractAnnotationProcessor; +import com.codename1.maven.annotations.AnnotatedClass; +import com.codename1.maven.annotations.AnnotationValues; +import com.codename1.maven.annotations.ProcessingException; +import com.codename1.maven.annotations.ProcessorContext; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeMap; + +/// Turns the `com.codename1.annotations.buildhints` annotations into the +/// `codename1.arg.*` key/value pairs the builders already consume. +/// +/// A build hint used to be a properties line that nothing checked, so a +/// misspelled name reached the build request, was never read, and was silently +/// dropped -- a green build with the setting simply not applied. Written as an +/// annotation the compiler catches the same mistake, and this processor is what +/// turns the checked form back into the wire form. +/// +/// The result is written to `META-INF/codenameone/build-hints.properties` in +/// `target/classes`, which puts it both on the simulator's classpath and inside +/// the jar uploaded to the build server. +public class BuildHintAnnotationProcessor extends AbstractAnnotationProcessor { + + /// Where the emitted hints land. Read by `CN1BuildMojo` before it writes the + /// build request, and by `Simulator` on startup. + public static final String MANIFEST_RESOURCE = "META-INF/codenameone/build-hints.properties"; + + /// Records which annotation attribute supplied each hint, so a later stage + /// -- the conflict message, the simulator's hint editor -- can name it. + private static final String ORIGIN_PREFIX = "cn1.buildHints.origin."; + + /// Stamps the emitted file with the main class it came from, so a stale or + /// foreign copy on the classpath can be recognised rather than merged. + private static final String MAIN_CLASS_KEY = "cn1.buildHints.mainClass"; + + /// hint name to value, sorted so the emitted bytes are stable. + private final Map hints = new TreeMap(); + /// hint name to "@Ios(pods)". + private final Map origins = new TreeMap(); + /// Classes carrying a build hint annotation, in discovery order. + private final List annotated = new ArrayList(); + + @Override + public Set getAnnotationDescriptors() { + return new LinkedHashSet(BuildHintAnnotationBinding.descriptors()); + } + + @Override + public void start(ProcessorContext ctx) throws ProcessingException { + hints.clear(); + origins.clear(); + annotated.clear(); + } + + @Override + public void processClass(AnnotatedClass cls, ProcessorContext ctx) throws ProcessingException { + Set descriptors = getAnnotationDescriptors(); + + // @Target(TYPE) already rejects a method or field placement at compile + // time, but @Target is a front-end check and this reads bytecode: a + // class produced another way could still carry one, and silently + // ignoring it would be the exact failure this feature removes. + for (String d : cls.getAllAnnotationDescriptors()) { + if (descriptors.contains(d) && !cls.getClassAnnotations().containsKey(d)) { + ctx.error(cls, "@" + simpleName(d) + " is a build hint annotation and belongs on " + + "the class itself, not on one of its members."); + } + } + + boolean carriesAny = false; + for (Map.Entry e : cls.getClassAnnotations().entrySet()) { + if (descriptors.contains(e.getKey())) { + carriesAny = true; + } + } + if (!carriesAny) { + return; + } + annotated.add(cls); + + for (Map.Entry e : cls.getClassAnnotations().entrySet()) { + String descriptor = e.getKey(); + if (!descriptors.contains(descriptor)) { + continue; + } + AnnotationValues values = e.getValue(); + // Only what the developer actually wrote: javac omits a member left + // at its default from the class file, and that absence is how an + // unset attribute is distinguished from one set to the default + // value. Reading through a getXxxOrDefault here would write a hint + // for every attribute of every annotation used. + for (Map.Entry member : values.all().entrySet()) { + String hint = BuildHintAnnotationBinding.hintFor(descriptor, member.getKey()); + if (hint == null) { + ctx.error(cls, "@" + simpleName(descriptor) + "(" + member.getKey() + + ") is not a known build hint. The catalog and the annotation " + + "have drifted; regenerate with " + + "scripts/gen-build-hint-annotations.sh."); + continue; + } + String value = wireValue(cls, descriptor, member.getKey(), member.getValue(), + hint, ctx); + if (value == null) { + continue; + } + String origin = "@" + simpleName(descriptor) + "(" + member.getKey() + ")"; + String previous = hints.put(hint, value); + if (previous != null && !previous.equals(value)) { + ctx.error(cls, "Build hint " + hint + " is set twice with different values: " + + origins.get(hint) + " and " + origin + "."); + } + origins.put(hint, origin); + } + } + } + + @Override + public void finish(ProcessorContext ctx) throws ProcessingException { + if (annotated.isEmpty()) { + // The last annotation was removed. The Mojo only writes emitted + // resources, it never deletes ones a processor stopped emitting, so + // without this yesterday's hints would stay in target/classes and + // ship inside the jar. + deleteGenerated(ctx); + return; + } + checkPlacement(ctx); + checkConflicts(ctx); + if (ctx.hasErrors()) { + return; + } + ctx.emitResource(MANIFEST_RESOURCE, serialize(ctx)); + ctx.getLog().info("cn1: " + hints.size() + " build hint(s) from annotations on " + + annotated.get(0).getBinaryName()); + } + + /// Build hints configure the application, so they belong on the class the + /// project already names as its entry point. + /// + /// Accepting them anywhere would mean two classes could set the same hint + /// and the winner would depend on the order `File.listFiles` happened to + /// return -- and it would scatter the effective build configuration across + /// the source tree, which is the problem the properties file already had. + private void checkPlacement(ProcessorContext ctx) { + String main = ctx.getMainClassBinaryName(); + if (main == null) { + ctx.error(annotated.get(0), + "Build hint annotations are only supported in a Codename One application, " + + "and this module declares no codename1.mainName."); + return; + } + for (AnnotatedClass cls : annotated) { + if (!main.equals(cls.getBinaryName())) { + ctx.error(cls, "Build hint annotations belong on the application's main class, " + + main + ", but this one carries them. Move them there, or set the hint " + + "in codenameone_settings.properties."); + } + } + } + + /// A hint has one source of truth. Setting it in both places means the two + /// can disagree, and nothing would say which won. + private void checkConflicts(ProcessorContext ctx) { + Properties settings = ctx.getProjectSettings(); + if (settings == null) { + return; + } + Map lines = propertyLines(ctx); + for (Map.Entry e : hints.entrySet()) { + // An alias and its target name one setting, so declaring the alias + // in the file still collides with the annotation. + Set names = new LinkedHashSet(); + names.add(e.getKey()); + for (BuildHints.Hint h : BuildHints.entries()) { + if (e.getKey().equals(h.aliasOf()) || e.getKey().equals( + BuildHints.canonicalName(h.name()))) { + names.add(h.name()); + } + } + for (String name : names) { + String key = BuildHints.ARG_PREFIX + name; + if (settings.getProperty(key) == null) { + continue; + } + StringBuilder sb = new StringBuilder(); + sb.append(key).append(" is declared twice.\n"); + sb.append(" annotation : ").append(origins.get(e.getKey())) + .append(" on ").append(annotated.get(0).getBinaryName()).append('\n'); + sb.append(" properties : "); + File f = settingsFile(ctx); + sb.append(f == null ? "codenameone_settings.properties" : f.getPath()); + Integer line = lines.get(key); + if (line != null) { + sb.append(':').append(line); + } + sb.append('\n'); + sb.append(" ").append(key).append('=') + .append(settings.getProperty(key)).append('\n'); + sb.append(" A build hint has one source of truth. Delete the properties line " + + "and keep the annotation, or delete the annotation attribute and keep " + + "the line. (-D").append(key).append("=... overrides either and is not " + + "a conflict.)"); + ctx.error(annotated.get(0), sb.toString()); + } + } + } + + private File settingsFile(ProcessorContext ctx) { + File dir = ctx.getProjectDir(); + if (dir == null) { + return null; + } + File f = new File(dir, "codenameone_settings.properties"); + return f.exists() ? f : null; + } + + /// Best-effort key to line number, so the conflict message can point at the + /// offending line. Properties escaping means an exotic key may not match; + /// the message then names the file only rather than guessing. + private Map propertyLines(ProcessorContext ctx) { + Map out = new LinkedHashMap(); + File f = settingsFile(ctx); + if (f == null) { + return out; + } + BufferedReader r = null; + try { + r = new BufferedReader(new InputStreamReader(new FileInputStream(f), "ISO-8859-1")); + String line; + int n = 0; + while ((line = r.readLine()) != null) { + n++; + String t = line.trim(); + if (t.length() == 0 || t.charAt(0) == '#' || t.charAt(0) == '!') { + continue; + } + int eq = t.indexOf('='); + int colon = t.indexOf(':'); + int split = eq < 0 ? colon : (colon < 0 ? eq : Math.min(eq, colon)); + if (split <= 0) { + continue; + } + String key = t.substring(0, split).trim(); + if (!out.containsKey(key)) { + out.put(key, Integer.valueOf(n)); + } + } + } catch (IOException ex) { + ctx.getLog().debug("cn1: could not read " + f + " for line numbers: " + ex.getMessage()); + } finally { + if (r != null) { + try { + r.close(); + } catch (IOException ignored) { + // read-only stream; nothing useful to do + } + } + } + return out; + } + + /// Converts one annotation member value to the string the build receives. + /// + /// Returns null when the value could not be converted, having reported it. + private String wireValue(AnnotatedClass cls, String descriptor, String member, Object raw, + String hint, ProcessorContext ctx) { + if (raw instanceof Boolean || raw instanceof Number || raw instanceof Character) { + return String.valueOf(raw); + } + if (raw instanceof String) { + return (String) raw; + } + // ASM reports an enum constant as { descriptor, CONSTANT_NAME }. The + // constant name is not the value the builder compares against, and a + // builder silently falls back to its default on a value it does not + // recognise, so guessing here would fail invisibly. + if (raw instanceof String[]) { + String[] pair = (String[]) raw; + if (pair.length == 2) { + String wire = BuildHintAnnotationBinding.wireValue(pair[0], pair[1]); + if (wire == null) { + ctx.error(cls, "@" + simpleName(descriptor) + "(" + member + ") uses the " + + "constant " + pair[1] + ", which the build hint catalog does not " + + "map to a value. Regenerate with " + + "scripts/gen-build-hint-annotations.sh."); + return null; + } + return wire; + } + } + if (raw instanceof List) { + String separator = BuildHints.separatorFor(hint); + if (separator.length() == 0) { + ctx.error(cls, "@" + simpleName(descriptor) + "(" + member + ") is a list but the " + + "catalog gives " + hint + " no separator, so its values would run " + + "together."); + return null; + } + StringBuilder sb = new StringBuilder(); + for (Object item : (List) raw) { + if (sb.length() > 0) { + sb.append(separator); + } + String itemValue = wireValue(cls, descriptor, member, item, hint, ctx); + if (itemValue == null) { + return null; + } + sb.append(itemValue); + } + return sb.toString(); + } + ctx.error(cls, "@" + simpleName(descriptor) + "(" + member + ") has a value this " + + "processor cannot convert: " + raw); + return null; + } + + /// Serializes deterministically. + /// + /// Not `Properties.store`: it writes a timestamp comment, so the bytes would + /// differ on every build. That churns the resource in every incremental + /// build and defeats the staged-jar staleness comparison in `CN1BuildMojo`. + private byte[] serialize(ProcessorContext ctx) throws ProcessingException { + StringBuilder sb = new StringBuilder(); + sb.append("# Generated from build hint annotations by the Codename One Maven plugin.\n"); + sb.append("# Edit the annotations on the main class, not this file.\n"); + String main = ctx.getMainClassBinaryName(); + if (main != null) { + sb.append(MAIN_CLASS_KEY).append('=').append(escape(main)).append('\n'); + } + for (Map.Entry e : hints.entrySet()) { + sb.append(escape(BuildHints.ARG_PREFIX + e.getKey())).append('=') + .append(escape(e.getValue())).append('\n'); + } + for (Map.Entry e : origins.entrySet()) { + sb.append(escape(ORIGIN_PREFIX + e.getKey())).append('=') + .append(escape(e.getValue())).append('\n'); + } + try { + return sb.toString().getBytes("ISO-8859-1"); + } catch (UnsupportedEncodingException ex) { + throw new ProcessingException("ISO-8859-1 is unavailable", ex); + } + } + + /// Applies the escaping `java.util.Properties` expects, so a value holding a + /// newline -- `gradleDependencies` legitimately does -- survives the round + /// trip. + static String escape(String s) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '\\': sb.append("\\\\"); break; + case '\n': sb.append("\\n"); break; + case '\r': sb.append("\\r"); break; + case '\t': sb.append("\\t"); break; + case '=': sb.append("\\="); break; + case ':': sb.append("\\:"); break; + case '#': sb.append("\\#"); break; + case '!': sb.append("\\!"); break; + case ' ': sb.append(i == 0 ? "\\ " : " "); break; + default: + if (c < 0x20 || c > 0x7e) { + sb.append(String.format("\\u%04x", Integer.valueOf(c))); + } else { + sb.append(c); + } + } + } + return sb.toString(); + } + + private void deleteGenerated(ProcessorContext ctx) { + File f = new File(ctx.getOutputClassDir(), MANIFEST_RESOURCE); + if (f.exists() && !f.delete()) { + ctx.getLog().warn("cn1: could not remove stale " + f + "; it would be packaged " + + "with hints the project no longer declares"); + } + } + + private static String simpleName(String descriptor) { + String s = descriptor; + if (s.startsWith("L") && s.endsWith(";")) { + s = s.substring(1, s.length() - 1); + } + int slash = s.lastIndexOf('/'); + return slash >= 0 ? s.substring(slash + 1) : s; + } +} diff --git a/maven/codenameone-maven-plugin/src/main/resources/META-INF/services/com.codename1.maven.annotations.AnnotationProcessor b/maven/codenameone-maven-plugin/src/main/resources/META-INF/services/com.codename1.maven.annotations.AnnotationProcessor index 52e2d775b5b..965c0ff6c46 100644 --- a/maven/codenameone-maven-plugin/src/main/resources/META-INF/services/com.codename1.maven.annotations.AnnotationProcessor +++ b/maven/codenameone-maven-plugin/src/main/resources/META-INF/services/com.codename1.maven.annotations.AnnotationProcessor @@ -7,3 +7,4 @@ com.codename1.maven.processors.ProtoMessageAnnotationProcessor com.codename1.maven.processors.GrpcClientAnnotationProcessor com.codename1.maven.processors.GraphQLClientAnnotationProcessor com.codename1.maven.processors.AppIntentAnnotationProcessor +com.codename1.maven.processors.BuildHintAnnotationProcessor diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java new file mode 100644 index 00000000000..b9b8e0ba559 --- /dev/null +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.maven.processors; + +import com.codename1.maven.annotations.AnnotatedClass; +import com.codename1.maven.annotations.ClassScanner; +import com.codename1.maven.annotations.JavaSourceCompiler; +import com.codename1.maven.annotations.ProcessorContext; + +import org.apache.maven.plugin.logging.SystemStreamLog; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.ByteArrayInputStream; +import java.net.URL; +import java.util.Arrays; +import java.util.Map; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/// Covers the conversion from typed annotation back to wire-format build hint. +/// +/// The cases that matter most are the silent ones: a hint written for an +/// attribute the developer never set, an enum written as its constant name +/// rather than the value the builder compares against, and a list joined with +/// the wrong delimiter. None of those fail a build -- the builder falls back to +/// a default or writes a malformed fragment -- so only a test catches them. +public class BuildHintAnnotationProcessorTest { + + @Rule + public TemporaryFolder tmp = new TemporaryFolder(); + + private static final String MAIN = "com.example.MyApp"; + + // ------------------------------------------------------------------ + // value conversion + // ------------------------------------------------------------------ + + @Test + public void aBooleanAttributeIsWrittenAsTrueOrFalse() throws Exception { + Properties p = hintsOf("@Ios(newStorageLocation = true)"); + assertEquals("true", p.getProperty("codename1.arg.ios.newStorageLocation")); + + p = hintsOf("@Ios(newStorageLocation = false)"); + assertEquals("false", p.getProperty("codename1.arg.ios.newStorageLocation")); + } + + @Test + public void anIntAttributeIsStringified() throws Exception { + Properties p = hintsOf("@Desktop(width = 1280, height = 720)"); + assertEquals("1280", p.getProperty("codename1.arg.desktop.width")); + assertEquals("720", p.getProperty("codename1.arg.desktop.height")); + } + + @Test + public void aStringAttributeIsWrittenVerbatim() throws Exception { + Properties p = hintsOf("@Ios(teamId = \"ABCDE12345\")"); + assertEquals("ABCDE12345", p.getProperty("codename1.arg.ios.teamId")); + } + + /// The builder compares against the catalog's value, not the constant name. + /// `IOS7` happens to lowercase to `ios7`, but `INTERNAL_ONLY` does not + /// lowercase to `internalOnly`, and a builder given an unrecognized value + /// silently uses its default -- so a name-based conversion would fail with + /// no diagnostic anywhere. + @Test + public void anEnumAttributeUsesTheCatalogValueNotTheConstantName() throws Exception { + Properties p = hintsOf("@Android(installLocation = InstallLocation.INTERNAL_ONLY)"); + assertEquals("internalOnly", p.getProperty("codename1.arg.android.installLocation")); + + p = hintsOf("@Ios(themeMode = IosThemeMode.IOS7)"); + assertEquals("ios7", p.getProperty("codename1.arg.ios.themeMode")); + + p = hintsOf("@Desktop(titleBar = DesktopTitleBar.TOOLBAR)"); + assertEquals("toolbar", p.getProperty("codename1.arg.desktop.titleBar")); + } + + @Test + public void aStringArrayIsJoinedWithTheHintsOwnSeparator() throws Exception { + // ios.pods is comma delimited, ios.add_libs is semicolon delimited -- + // the same shape in Java, two different wire formats. + Properties p = hintsOf("@Ios(pods = {\"Alamofire\", \"SwiftyJSON\"}, " + + "addLibs = {\"libz.tbd\", \"libsqlite3.tbd\"})"); + assertEquals("Alamofire,SwiftyJSON", p.getProperty("codename1.arg.ios.pods")); + assertEquals("libz.tbd;libsqlite3.tbd", p.getProperty("codename1.arg.ios.add_libs")); + } + + @Test + public void aNewlineDelimitedListSurvivesThePropertiesRoundTrip() throws Exception { + Properties p = hintsOf("@Android(proguardKeep = {\"-keep class com.a.** { *; }\", " + + "\"-keep class com.b.** { *; }\"})"); + assertEquals("-keep class com.a.** { *; }\n-keep class com.b.** { *; }", + p.getProperty("codename1.arg.android.proguardKeep")); + } + + // ------------------------------------------------------------------ + // set vs unset + // ------------------------------------------------------------------ + + /// The load-bearing one. javac omits a member left at its default from the + /// class file, which is the only thing distinguishing "not set" from "set + /// to the default". Reading attributes through a getOrDefault would write + /// a hint for every attribute of every annotation the project uses. + @Test + public void anAttributeThatWasNotWrittenProducesNoHint() throws Exception { + Properties p = hintsOf("@Ios(pods = {\"Alamofire\"})"); + assertEquals("Alamofire", p.getProperty("codename1.arg.ios.pods")); + assertNull("an unset attribute must not be written at all", + p.getProperty("codename1.arg.ios.newStorageLocation")); + assertNull(p.getProperty("codename1.arg.ios.objC")); + assertNull(p.getProperty("codename1.arg.ios.teamId")); + } + + /// The other half of the same contract: a value the developer typed is + /// written even when it equals the annotation's declared default, because + /// typing it is a statement of intent. + @Test + public void anExplicitlyWrittenDefaultValueIsStillEmitted() throws Exception { + // ios.objC is declared `default true` by the generator. + Properties p = hintsOf("@Ios(objC = true)"); + assertEquals("true", p.getProperty("codename1.arg.ios.objC")); + } + + // ------------------------------------------------------------------ + // determinism and cleanup + // ------------------------------------------------------------------ + + @Test + public void theEmittedResourceIsByteStableAcrossRuns() throws Exception { + String src = "@Ios(pods = {\"A\", \"B\"}, teamId = \"T\")\n@Desktop(width = 640)"; + byte[] first = rawResource(src); + byte[] second = rawResource(src); + assertTrue("the emitted resource must not change between identical builds", + Arrays.equals(first, second)); + } + + @Test + public void removingTheLastAnnotationRemovesTheGeneratedResource() throws Exception { + File classes = compile("@Ios(teamId = \"T\")"); + ProcessorContext ctx = run(classes, settings(), MAIN, true); + File emitted = new File(classes, + BuildHintAnnotationProcessor.MANIFEST_RESOURCE); + emitted.getParentFile().mkdirs(); + FileOutputStream out = new FileOutputStream(emitted); + out.write(ctx.getEmittedResources().get( + BuildHintAnnotationProcessor.MANIFEST_RESOURCE)); + out.close(); + assertTrue(emitted.exists()); + + // Recompile with no build hint annotation at all. + File plain = compile(""); + // Point the processor at the directory still holding yesterday's file. + copyInto(plain, emitted); + run(plain, settings(), MAIN, true); + assertFalse("a stale build-hints resource would ship hints the project no longer " + + "declares", new File(plain, + BuildHintAnnotationProcessor.MANIFEST_RESOURCE).exists()); + } + + // ------------------------------------------------------------------ + // placement + // ------------------------------------------------------------------ + + @Test + public void annotationsOnANonMainClassAreRejected() throws Exception { + File classes = compile("@Ios(teamId = \"T\")"); + ProcessorContext ctx = run(classes, settings(), "com.example.SomethingElse", false); + assertErrorContaining(ctx, "belong on the application's main class"); + } + + @Test + public void aModuleWithNoMainClassIsRejected() throws Exception { + File classes = compile("@Ios(teamId = \"T\")"); + ProcessorContext ctx = run(classes, settings(), null, false); + assertErrorContaining(ctx, "declares no codename1.mainName"); + } + + /// A project that uses none of these annotations must not start failing + /// because it has no main class -- a cn1lib, for instance. + @Test + public void aModuleWithNoAnnotationsAndNoMainClassIsFine() throws Exception { + File classes = compile(""); + ProcessorContext ctx = run(classes, settings(), null, true); + assertFalse(ctx.hasErrors()); + } + + // ------------------------------------------------------------------ + // conflicts with the properties file + // ------------------------------------------------------------------ + + @Test + public void aHintSetInBothPlacesIsAnError() throws Exception { + Properties s = settings(); + s.setProperty("codename1.arg.ios.teamId", "FROMFILE"); + File classes = compile("@Ios(teamId = \"FROMANNOTATION\")"); + ProcessorContext ctx = run(classes, s, MAIN, false); + assertErrorContaining(ctx, "codename1.arg.ios.teamId is declared twice"); + assertErrorContaining(ctx, "@Ios(teamId)"); + } + + @Test + public void aHintOnlyInThePropertiesFileIsFine() throws Exception { + Properties s = settings(); + s.setProperty("codename1.arg.ios.plistInject", "X"); + File classes = compile("@Ios(teamId = \"T\")"); + ProcessorContext ctx = run(classes, s, MAIN, true); + assertFalse(ctx.hasErrors()); + } + + /// A commented-out line is not a declaration, and the archetype ships + /// several. Properties.load skips them, so this is really a guard against + /// anyone reintroducing a hand-rolled line scan. + @Test + public void aCommentedOutPropertyIsNotAConflict() throws Exception { + Properties s = new Properties(); + s.load(new ByteArrayInputStream( + ("codename1.mainName=MyApp\ncodename1.packageName=com.example\n" + + "#codename1.arg.ios.teamId=OLD\n").getBytes("ISO-8859-1"))); + File classes = compile("@Ios(teamId = \"T\")"); + ProcessorContext ctx = run(classes, s, MAIN, true); + assertFalse(ctx.hasErrors()); + } + + // ------------------------------------------------------------------ + // helpers + // ------------------------------------------------------------------ + + private static String source(String annotations) { + return "package com.example;\n" + + "import com.codename1.annotations.buildhints.*;\n" + + annotations + "\n" + + "public class MyApp {\n}\n"; + } + + private File compile(String annotations) throws Exception { + File classes = tmp.newFolder(); + JavaSourceCompiler.compile( + JavaSourceCompiler.singleSource(MAIN, source(annotations)), + classes, Arrays.asList(testClassesDir(), coreJar())); + return classes; + } + + private ProcessorContext run(File classes, Properties settings, String mainClass, + boolean expectClean) throws Exception { + Map index = ClassScanner.scan(classes); + BuildHintAnnotationProcessor proc = new BuildHintAnnotationProcessor(); + ProcessorContext ctx = new ProcessorContext(classes, tmp.newFolder(), index, + new SystemStreamLog(), tmp.newFolder(), settings, mainClass); + proc.start(ctx); + for (AnnotatedClass cls : index.values()) { + proc.processClass(cls, ctx); + } + proc.finish(ctx); + if (expectClean && ctx.hasErrors()) { + StringBuilder sb = new StringBuilder("unexpected errors:\n"); + for (ProcessorContext.ProcessingError e : ctx.getErrors()) { + sb.append(" ").append(e).append('\n'); + } + fail(sb.toString()); + } + return ctx; + } + + private byte[] rawResource(String annotations) throws Exception { + ProcessorContext ctx = run(compile(annotations), settings(), MAIN, true); + byte[] bytes = ctx.getEmittedResources() + .get(BuildHintAnnotationProcessor.MANIFEST_RESOURCE); + assertTrue("build-hints.properties must be emitted", bytes != null); + return bytes; + } + + private Properties hintsOf(String annotations) throws Exception { + Properties p = new Properties(); + p.load(new ByteArrayInputStream(rawResource(annotations))); + return p; + } + + private static Properties settings() { + Properties p = new Properties(); + p.setProperty("codename1.mainName", "MyApp"); + p.setProperty("codename1.packageName", "com.example"); + return p; + } + + private static void assertErrorContaining(ProcessorContext ctx, String fragment) { + assertTrue("expected a validation error", ctx.hasErrors()); + StringBuilder all = new StringBuilder(); + for (ProcessorContext.ProcessingError e : ctx.getErrors()) { + all.append(e).append('\n'); + } + assertTrue("expected an error containing \"" + fragment + "\" but got:\n" + all, + all.toString().contains(fragment)); + } + + private static void copyInto(File classesDir, File existing) throws Exception { + File target = new File(classesDir, BuildHintAnnotationProcessor.MANIFEST_RESOURCE); + target.getParentFile().mkdirs(); + java.nio.file.Files.copy(existing.toPath(), target.toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING); + } + + private static File testClassesDir() throws Exception { + URL url = BuildHintAnnotationProcessorTest.class.getProtectionDomain() + .getCodeSource().getLocation(); + return new File(url.toURI()); + } + + /// The generated annotations live in codenameone-core, which is already a + /// dependency of the plugin, so the compiled sources can reference them. + private static File coreJar() throws Exception { + URL url = Class.forName("com.codename1.annotations.buildhints.Ios") + .getProtectionDomain().getCodeSource().getLocation(); + return new File(url.toURI()); + } +} diff --git a/maven/integration-tests/all.sh b/maven/integration-tests/all.sh index e3854a3d131..04fe56dc8d0 100644 --- a/maven/integration-tests/all.sh +++ b/maven/integration-tests/all.sh @@ -9,6 +9,7 @@ bash cssfonts.sh bash native-interfaces.sh bash initializr-roundtrip-test.sh bash cn1app-archetype-test.sh +bash build-hint-annotations-test.sh bash cn1app-desktop-build-test.sh bash bare-bones-kotlin-test.sh bash migrate-kitchensink-test.sh diff --git a/maven/integration-tests/build-hint-annotations-test.sh b/maven/integration-tests/build-hint-annotations-test.sh new file mode 100755 index 00000000000..49d14ede752 --- /dev/null +++ b/maven/integration-tests/build-hint-annotations-test.sh @@ -0,0 +1,93 @@ +#!/bin/bash +# +# Build hints written as annotations must reach the build request, and the same +# hint set twice must fail. +# +# A build hint used to be an unchecked string: misspell it and the build stayed +# green while the setting silently did nothing. The annotations exist so the +# compiler catches that, and this test covers the part the compiler cannot -- +# that the annotation is actually converted back into the codename1.arg.* pair +# the builders read, and that it is not silently merged with a properties line +# saying something different. +SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" +set -e +source $SCRIPTPATH/inc/env.sh + +cd $SCRIPTPATH/build +rm -rf myapphints +mvn archetype:generate \ + -DarchetypeArtifactId=cn1app-archetype \ + -DarchetypeGroupId=com.codenameone \ + -DarchetypeVersion=$CN1_VERSION \ + -DartifactId=myapphints \ + -DgroupId=com.example \ + -Dversion=1.0-SNAPSHOT \ + -DmainName=MyApp \ + -DinteractiveMode=false + +cd myapphints +chmod 755 mvnw + +MAIN=common/src/main/java/com/example/MyApp.java +SETTINGS=common/codenameone_settings.properties + +echo "--- the generated project must already use annotations ---" +grep -q "com.codename1.annotations.buildhints" $MAIN \ + || { echo "FAIL: the archetype's main class does not import the build hint annotations"; exit 1; } +grep -q "^codename1.arg.ios.newStorageLocation" $SETTINGS \ + && { echo "FAIL: ios.newStorageLocation should have moved to @Ios, not stayed in $SETTINGS"; exit 1; } + +echo "--- add a hint of each shape ---" +perl -0pi -e 's/\@Ios\(/\@Ios(pods = {"Alamofire", "SwiftyJSON"}, teamId = "ABCDE12345", /' $MAIN +grep -q 'pods = {"Alamofire"' $MAIN || { echo "FAIL: could not patch $MAIN"; exit 1; } + +echo "--- process-classes must emit the hints ---" +./mvnw -B -q -pl common process-classes +EMITTED=common/target/classes/META-INF/codenameone/build-hints.properties +test -f $EMITTED || { echo "FAIL: $EMITTED was not emitted"; exit 1; } + +check() { + grep -qF "$1" $EMITTED || { echo "FAIL: expected '$1' in $EMITTED"; cat $EMITTED; exit 1; } +} +# a list joins with the hint's own separator, an enum uses the catalog's value +# rather than the constant name, and an unset attribute writes nothing at all +check "codename1.arg.ios.pods=Alamofire,SwiftyJSON" +check "codename1.arg.ios.teamId=ABCDE12345" +check "codename1.arg.ios.themeMode=modern" +check "codename1.arg.desktop.titleBar=native" +grep -q "codename1.arg.ios.objC" $EMITTED \ + && { echo "FAIL: an attribute nobody set must not be written"; exit 1; } + +echo "--- the hints must reach the build request ---" +# "Build target not supported" is thrown after the merged settings file is +# written, so this asserts the upload payload offline: no SDK, no cloud build. +set +e +./mvnw -B -q -DskipTests -Dcodename1.platform=javase \ + -Dcodename1.buildTarget=local-build-hint-probe package > /tmp/cn1-hints-build.log 2>&1 +set -e +MERGED=common/target/codenameone/antProject/codenameone_settings.properties +test -f $MERGED || MERGED=javase/target/codenameone/antProject/codenameone_settings.properties +if [ -f "$MERGED" ]; then + grep -q "codename1.arg.ios.pods=Alamofire,SwiftyJSON" $MERGED \ + || { echo "FAIL: annotation hints did not reach the build request"; cat $MERGED; exit 1; } + echo "OK: annotation hints reached $MERGED" +else + echo "NOTE: no build request was written for this target; skipping that assertion" +fi + +echo "--- declaring the same hint twice must fail ---" +echo "codename1.arg.ios.teamId=FROMFILE" >> $SETTINGS +set +e +./mvnw -B -pl common process-classes > /tmp/cn1-hints-conflict.log 2>&1 +STATUS=$? +set -e +if [ $STATUS -eq 0 ]; then + echo "FAIL: a hint set in both the annotation and $SETTINGS should fail the build" + exit 1 +fi +grep -q "codename1.arg.ios.teamId is declared twice" /tmp/cn1-hints-conflict.log \ + || { echo "FAIL: the conflict error did not name the hint"; tail -30 /tmp/cn1-hints-conflict.log; exit 1; } +grep -q "@Ios(teamId)" /tmp/cn1-hints-conflict.log \ + || { echo "FAIL: the conflict error did not name the annotation attribute"; exit 1; } + +echo "PASSED build-hint-annotations-test" diff --git a/maven/pom.xml b/maven/pom.xml index 303a83ec859..8184e0fff39 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -81,6 +81,7 @@ cn1-binaries platform-feature-catalog + build-hint-catalog java-runtime core factory diff --git a/scripts/build-hint-catalog-baseline.txt b/scripts/build-hint-catalog-baseline.txt new file mode 100644 index 00000000000..1c1820530bf --- /dev/null +++ b/scripts/build-hint-catalog-baseline.txt @@ -0,0 +1,8 @@ +# Build hints read by a builder or a mojo that the catalog does not describe, +# as of the day this gate was added. +# +# This is a ratchet, not an allow-list: new code must not add entries. Delete a +# line when the hint is added to maven/build-hint-catalog. Regenerate with +# scripts/check-build-hint-catalog.sh --write-baseline +# +# Format: |: diff --git a/scripts/build_hint_miner.py b/scripts/build_hint_miner.py new file mode 100644 index 00000000000..47498c3547f --- /dev/null +++ b/scripts/build_hint_miner.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +"""Mines every build hint the Maven plugin and the builders read. + +Three accessor shapes reach a hint; a getArg() grep alone misses the whole +@Desktop group, which is read only by a private arg() helper in +GenerateDesktopAppWrapperMojo. + +Arguments are split with a paren/quote-balanced scan rather than a regex, +because calls nest: getArg("ios.urlSchemes", getArg("ios.urlScheme", "")). +A regex that stops at the first comma both mis-reads the outer default and +consumes the inner call, silently dropping a hint from the catalog. +""" +import re, os, sys, json, collections + +ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +SRC = os.path.join(ROOT, "maven/codenameone-maven-plugin/src/main/java/com/codename1") + +OPENERS = [ + (re.compile(r'\bgetArg\(\s*"'), False), + (re.compile(r'(? 1 else "" + if not LITERAL_DEFAULT.fullmatch(default or "null"): + default = "" + line = text.count("\n", 0, m.start()) + 1 + hits[key].append((default or "null", rel, line)) + +if __name__ == "__main__": + print(f"distinct keys mined: {len(hits)}", file=sys.stderr) + out = sys.argv[1] if len(sys.argv) > 1 else "-" + payload = {k: v for k, v in sorted(hits.items())} + if out == "-": + json.dump(payload, sys.stdout, indent=1) + else: + json.dump(payload, open(out, "w"), indent=1) diff --git a/scripts/certificatewizard/common/codenameone_settings.properties b/scripts/certificatewizard/common/codenameone_settings.properties index 86cf88fa524..b6d065730e0 100644 --- a/scripts/certificatewizard/common/codenameone_settings.properties +++ b/scripts/certificatewizard/common/codenameone_settings.properties @@ -7,10 +7,4 @@ codename1.secondaryTitle=Certificate Wizard codename1.icon=icon.png codename1.cssTheme=true codename1.arg.java.version=17 -codename1.arg.nativeTheme=modern -codename1.arg.ios.themeMode=modern -codename1.arg.and.themeMode=modern -codename1.arg.desktop.width=1260 -codename1.arg.desktop.height=820 -codename1.arg.desktop.titleBar=native codename1.kotlin=false diff --git a/scripts/certificatewizard/common/src/main/java/com/codename1/certificatewizard/CertificateWizard.java b/scripts/certificatewizard/common/src/main/java/com/codename1/certificatewizard/CertificateWizard.java index 116a660dd0a..99254d5b752 100644 --- a/scripts/certificatewizard/common/src/main/java/com/codename1/certificatewizard/CertificateWizard.java +++ b/scripts/certificatewizard/common/src/main/java/com/codename1/certificatewizard/CertificateWizard.java @@ -67,7 +67,12 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; +import com.codename1.annotations.buildhints.*; +@Android(themeMode = AndroidThemeMode.MODERN) +@Build(nativeTheme = NativeThemeMode.MODERN) +@Desktop(height = 820, titleBar = DesktopTitleBar.NATIVE, width = 1260) +@Ios(themeMode = IosThemeMode.MODERN) public class CertificateWizard extends Lifecycle { public enum Section { OVERVIEW, CREDENTIAL, CERTIFICATES, BUNDLES, DEVICES, PROFILES, APNS, MAC, ANDROID, WINDOWS, MAINTENANCE } diff --git a/scripts/check-build-hint-catalog.py b/scripts/check-build-hint-catalog.py new file mode 100755 index 00000000000..eb8c4c787dc --- /dev/null +++ b/scripts/check-build-hint-catalog.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +"""Reports build hints the code reads that the catalog does not describe. + +A hint the catalog does not know about is invisible to everything downstream: +it gets no annotation, no doc row, no entry in the Settings tool, and no +value checking. That is how `android.xPermissions` shipped in our own agent +reference for a hint the builder actually spells `android.xpermissions` -- +green build, no effect, nobody noticed. + +Held against a baseline rather than failing outright: a large tail of hints +predates the catalog. The point is that *new* code cannot add another one. +""" +import fnmatch, json, os, re, subprocess, sys + +ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, os.path.join(ROOT, "scripts")) +BASELINE = os.path.join(ROOT, "scripts", "build-hint-catalog-baseline.txt") +CATALOG_CLASSES = os.path.join(ROOT, "maven/build-hint-catalog/target/classes") + + +def catalog(): + """(known names, dynamic patterns) straight out of the compiled catalog.""" + src = os.path.join(ROOT, "maven/build-hint-catalog/src/main/java/com/codename1/build/shared") + names, patterns = set(), set() + for fn in sorted(os.listdir(src)): + if not fn.startswith("BuildHints") or not fn.endswith(".java"): + continue + text = open(os.path.join(src, fn), encoding="utf-8").read() + for m in re.finditer(r'new Hint\("((?:[^"\\]|\\.)*)"\)', text): + names.add(m.group(1)) + for m in re.finditer(r'\.dynamic\("((?:[^"\\]|\\.)*)"\)', text): + patterns.add(m.group(1)) + # BuildHintsDynamic registers through a helper; take its literals too + for m in re.finditer(r'family\(h,\s*"((?:[^"\\]|\\.)*)"', text): + names.add(m.group(1)) + patterns.add(m.group(1)) + return names, patterns + + +DOC_ROOTS = [ + "scripts/initializr/common/src/main/resources/skill", + "maven/cn1app-archetype/src/main/resources/archetype-resources", +] + + +def documented_hints(): + """Every codename1.arg.* key our own docs and templates name. + + These are read by people and by coding agents, and a key that no builder + reads is silently inert -- which is exactly how android.xPermissions, + android.minSdkVersion and android.sdkVersion came to be recommended in the + agent reference for hints the builder spells differently or not at all. + """ + found = {} + for root in DOC_ROOTS: + base = os.path.join(ROOT, root) + for dirpath, _, files in os.walk(base): + for fn in files: + if not fn.endswith((".md", ".properties", ".java", ".adoc")): + continue + path = os.path.join(dirpath, fn) + try: + text = open(path, encoding="utf-8", errors="replace").read() + except OSError: + continue + for m in re.finditer(r'codename1\.arg\.([A-Za-z][A-Za-z0-9_.]*)', text): + key = m.group(1) + # "codename1.arg.var." is written with a placeholder suffix; + # keep the trailing dot so it still matches the var.* family. + if key.endswith("."): + key += "*" + found.setdefault(key, os.path.relpath(path, ROOT)) + return found + + +def main(): + write = "--write-baseline" in sys.argv + import build_hint_miner as miner + + known, patterns = catalog() + if not known: + print("check-build-hint-catalog: found no catalog entries -- is the source tree intact?", + file=sys.stderr) + return 2 + + findings = [] + for key, sites in sorted(miner.hits.items()): + if key in known: + continue + if any(fnmatch.fnmatch(key, p) for p in patterns): + continue + rel, line = sites[0][1], sites[0][2] + findings.append(f"{key}|{rel}:{line}") + + if write: + with open(BASELINE, "w") as f: + f.write(HEADER) + for line in findings: + f.write(line + "\n") + print(f"check-build-hint-catalog: wrote {len(findings)} baseline entries") + return 0 + + baseline = set() + if os.path.exists(BASELINE): + for line in open(BASELINE): + line = line.strip() + if line and not line.startswith("#"): + baseline.add(line.split("|")[0]) + + current = {f.split("|")[0]: f for f in findings} + added = sorted(set(current) - baseline) + removed = sorted(baseline - set(current)) + + if added: + print("check-build-hint-catalog: build hints read by the code that the catalog " + "does not describe:", file=sys.stderr) + for key in added: + print(" " + current[key].replace("|", " read at "), file=sys.stderr) + print("\nAdd each one to maven/build-hint-catalog/.../BuildHints*.java. A hint the " + "catalog does not know about gets no annotation, no documentation and no " + "value checking.", file=sys.stderr) + if removed: + print("\ncheck-build-hint-catalog: these baseline entries are now catalogued; " + "delete them from\n scripts/build-hint-catalog-baseline.txt", file=sys.stderr) + for key in removed: + print(" " + key, file=sys.stderr) + if added or removed: + return 1 + + # Our own docs and project templates must not name a hint that does not exist. + doc_bad = [] + for key, where in sorted(documented_hints().items()): + if key in known: + continue + if any(fnmatch.fnmatch(key, p) for p in patterns): + continue + doc_bad.append(f"{key} named in {where}") + if doc_bad: + print("check-build-hint-catalog: our own documentation names build hints that do " + "not exist:", file=sys.stderr) + for line in doc_bad: + print(" " + line, file=sys.stderr) + print("\nA hint nothing reads is silently ignored, so a reader who copies it gets a " + "green build and no effect.", file=sys.stderr) + return 1 + + print(f"check-build-hint-catalog: {len(miner.hits)} hints read, all described by the catalog" + + (f" ({len(baseline)} baselined)" if baseline else "")) + return 0 + + +HEADER = """# Build hints read by a builder or a mojo that the catalog does not describe, +# as of the day this gate was added. +# +# This is a ratchet, not an allow-list: new code must not add entries. Delete a +# line when the hint is added to maven/build-hint-catalog. Regenerate with +# scripts/check-build-hint-catalog.sh --write-baseline +# +# Format: |: +""" + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/check-build-hint-catalog.sh b/scripts/check-build-hint-catalog.sh new file mode 100755 index 00000000000..ac276d5bcf1 --- /dev/null +++ b/scripts/check-build-hint-catalog.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# +# Fails when code reads a build hint that the catalog does not describe. +# +# Build hints are string keys. Nothing checks them, so a hint that is misspelled +# where it is read -- or added to a builder and nowhere else -- simply does +# nothing: the build is green and the feature is inert. The catalog in +# maven/build-hint-catalog is what gives every hint a type, a default, a value +# domain and a doc row, and it is what the @Ios/@Android annotations are +# generated from. A hint missing from it is invisible to all of that. +# +# scripts/check-build-hint-catalog.sh [--write-baseline] +# +# The result is held against scripts/build-hint-catalog-baseline.txt, a ratchet +# of pre-existing debt rather than an allow-list. That file is currently empty: +# every hint the code reads is described. Keep it that way -- a new entry means +# a new hint went in without a catalog row. +# +# Reads source, not bytecode, so nothing has to be built first and no module can +# silently drop out of coverage. +set -euo pipefail + +SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" +exec python3 "$SCRIPT_DIR/check-build-hint-catalog.py" "$@" diff --git a/scripts/cn1playground/common/codenameone_settings.properties b/scripts/cn1playground/common/codenameone_settings.properties index 454539b07fc..10505aa8793 100644 --- a/scripts/cn1playground/common/codenameone_settings.properties +++ b/scripts/cn1playground/common/codenameone_settings.properties @@ -2,14 +2,9 @@ codename1.android.keystore= codename1.android.keystoreAlias= codename1.android.keystorePassword= codename1.arg.block_server_registration=true -codename1.arg.ios.newStorageLocation=true -codename1.arg.ios.NSCameraUsageDescription=Some functionality of the application requires your camera # Preview the iOS Modern (liquid-glass) and Android Material 3 # themes inside the playground so users see the modern look when # they explore components. -codename1.arg.nativeTheme=modern -codename1.arg.ios.themeMode=modern -codename1.arg.and.themeMode=modern codename1.arg.java.version=17 codename1.arg.javascript.inject_proxy=false codename1.cssTheme=true diff --git a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java index f36d522986d..fe635fae6ba 100644 --- a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java +++ b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java @@ -55,7 +55,12 @@ import java.util.ArrayList; import java.util.Hashtable; import java.util.List; +import com.codename1.annotations.buildhints.*; +@Android(themeMode = AndroidThemeMode.MODERN) +@Build(nativeTheme = NativeThemeMode.MODERN) +@Ios(newStorageLocation = true, themeMode = IosThemeMode.MODERN) +@IosPrivacy(cameraUsageDescription = "Some functionality of the application requires your camera") public class CN1Playground extends Lifecycle { private static final boolean DEFAULT_DARK_MODE = true; private static final String THEME_ROLE = "playgroundThemeRole"; diff --git a/scripts/fidelity-app/common/codenameone_settings.properties b/scripts/fidelity-app/common/codenameone_settings.properties index d3f6f26ad8e..18061a29110 100644 --- a/scripts/fidelity-app/common/codenameone_settings.properties +++ b/scripts/fidelity-app/common/codenameone_settings.properties @@ -3,11 +3,7 @@ codename1.android.keystore=/Users/shai/dev/cn4/CodenameOne/scripts/fidelity-app/android/../common/androidCerts/KeyChain.ks codename1.android.keystoreAlias=androidKey codename1.android.keystorePassword=password -codename1.arg.android.gradleDep=implementation 'com.google.android.material\:material\:1.12.0' -codename1.arg.android.useAndroidX=true codename1.arg.ios.metal=true -codename1.arg.ios.newStorageLocation=true -codename1.arg.ios.uiscene=true codename1.arg.java.version=17 codename1.cssTheme=true codename1.displayName=Fidelity diff --git a/scripts/fidelity-app/common/src/main/java/com/codenameone/fidelity/FidelityApp.java b/scripts/fidelity-app/common/src/main/java/com/codenameone/fidelity/FidelityApp.java index 739b0c98598..5fb34da91d0 100644 --- a/scripts/fidelity-app/common/src/main/java/com/codenameone/fidelity/FidelityApp.java +++ b/scripts/fidelity-app/common/src/main/java/com/codenameone/fidelity/FidelityApp.java @@ -23,6 +23,7 @@ package com.codenameone.fidelity; import com.codename1.system.Lifecycle; +import com.codename1.annotations.buildhints.*; /** * Entry point for the native-theme fidelity test app. It is not an interactive @@ -31,6 +32,8 @@ * screenshots to the host over the CN1SS WebSocket, then prints * CN1SS:SUITE:FINISHED and exits. */ +@Android(gradleDep = {"implementation 'com.google.android.material:material:1.12.0'"}, useAndroidX = true) +@Ios(newStorageLocation = true, uiscene = true) public class FidelityApp extends Lifecycle { @Override public void runApp() { diff --git a/scripts/gamebuilder/common/codenameone_settings.properties b/scripts/gamebuilder/common/codenameone_settings.properties index f38391dcdd3..40645679eea 100644 --- a/scripts/gamebuilder/common/codenameone_settings.properties +++ b/scripts/gamebuilder/common/codenameone_settings.properties @@ -7,11 +7,5 @@ codename1.secondaryTitle=Game Builder codename1.icon=icon.png codename1.cssTheme=true codename1.arg.java.version=17 -codename1.arg.nativeTheme=modern -codename1.arg.ios.themeMode=modern -codename1.arg.and.themeMode=modern -codename1.arg.desktop.width=1280 -codename1.arg.desktop.height=800 -# native window chrome: OS title bar + native macOS/Windows menu bar (File/Edit/View…) -codename1.arg.desktop.titleBar=native +# native window chrome: OS title bar + native macOS/Windows menu bar (File/Edit/View…) codename1.kotlin=false diff --git a/scripts/gamebuilder/common/src/main/java/com/codename1/gamebuilder/GameBuilder.java b/scripts/gamebuilder/common/src/main/java/com/codename1/gamebuilder/GameBuilder.java index 7dcfcd8c72e..315f0637232 100644 --- a/scripts/gamebuilder/common/src/main/java/com/codename1/gamebuilder/GameBuilder.java +++ b/scripts/gamebuilder/common/src/main/java/com/codename1/gamebuilder/GameBuilder.java @@ -75,6 +75,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import com.codename1.annotations.buildhints.*; /// The Codename One game builder: a visual level / map editor for the /// `com.codename1.gaming` engine, adapted from the "GameForge" design. @@ -82,6 +83,10 @@ /// Every control is wired; the live preview plays in-place (toggle, no navigation) so /// there is never a dead-end screen. Behavior and structure are covered by tests /// (EditorControllerTest, GameBuilderStructureHarness). +@Android(themeMode = AndroidThemeMode.MODERN) +@Build(nativeTheme = NativeThemeMode.MODERN) +@Desktop(height = 800, titleBar = DesktopTitleBar.NATIVE, width = 1280) +@Ios(themeMode = IosThemeMode.MODERN) public class GameBuilder extends Lifecycle { private EditorController controller; diff --git a/scripts/gen-build-hint-annotations.sh b/scripts/gen-build-hint-annotations.sh new file mode 100755 index 00000000000..27fb5ebb814 --- /dev/null +++ b/scripts/gen-build-hint-annotations.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# +# Regenerates the build hint annotations in +# CodenameOne/src/com/codename1/annotations/buildhints from the catalog in +# maven/build-hint-catalog, along with the BuildHintAnnotationBinding table the +# annotation processor reads back. +# +# scripts/gen-build-hint-annotations.sh # write into the tree +# scripts/gen-build-hint-annotations.sh --check # fail if anything changed +# +# The output is checked in. CodenameOne/src is compiled by the Maven core +# module, the Ant/NetBeans project and the IDE projects alike, and only the +# first would see sources generated into target/ -- the others would quietly +# build a codenameone-core.jar without the annotations in it. Checking the +# sources in also means @Ios( completes in the IDE, which is the point. +set -euo pipefail + +SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" +REPO_ROOT="$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)" +CATALOG="$REPO_ROOT/maven/build-hint-catalog" +CLASSES="$CATALOG/target/classes" +ANN_ROOT="$REPO_ROOT/CodenameOne/src" +CATALOG_SRC="$CATALOG/src/main/java" + +check=0 +[ "${1:-}" = "--check" ] && check=1 + +if [ ! -f "$CLASSES/com/codename1/build/shared/BuildHintCodeGenerator.class" ]; then + echo "gen-build-hint-annotations: building the catalog" >&2 + (cd "$REPO_ROOT/maven" && mvn -q -B -pl build-hint-catalog package -DskipTests) +fi + +SKILL_REF="$REPO_ROOT/scripts/initializr/common/src/main/resources/skill/references/build-hints.md" +JAVASE_SRC="$REPO_ROOT/Ports/JavaSE/src" +GUIDE_TABLE="$REPO_ROOT/docs/developer-guide/_generated-build-hints.adoc" + +java -cp "$CLASSES" com.codename1.build.shared.BuildHintCodeGenerator \ + "$ANN_ROOT" "$CATALOG_SRC" "$SKILL_REF" "$JAVASE_SRC" "$GUIDE_TABLE" + +if [ "$check" -eq 1 ]; then + targets=("CodenameOne/src/com/codename1/annotations/buildhints" + "maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintAnnotationBinding.java" + "scripts/initializr/common/src/main/resources/skill/references/build-hints.md" + "Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java" + "docs/developer-guide/_generated-build-hints.adoc") + if ! git -C "$REPO_ROOT" diff --quiet -- "${targets[@]}" \ + || [ -n "$(git -C "$REPO_ROOT" ls-files --others --exclude-standard -- "${targets[@]}")" ]; then + echo "::error::Generated build hint annotations are out of date." >&2 + echo "Run scripts/gen-build-hint-annotations.sh and commit the result." >&2 + git -C "$REPO_ROOT" --no-pager diff -- "${targets[@]}" >&2 || true + git -C "$REPO_ROOT" ls-files --others --exclude-standard -- "${targets[@]}" >&2 || true + exit 1 + fi + echo "gen-build-hint-annotations: generated sources are up to date" +fi diff --git a/scripts/guibuilder/common/codenameone_settings.properties b/scripts/guibuilder/common/codenameone_settings.properties index 0722854a1c0..75cad311745 100644 --- a/scripts/guibuilder/common/codenameone_settings.properties +++ b/scripts/guibuilder/common/codenameone_settings.properties @@ -5,8 +5,3 @@ codename1.version=1.0 codename1.vendor=Codename One codename1.cssTheme=true codename1.arg.java.version=17 -codename1.arg.nativeTheme=modern -codename1.arg.desktop.width=1440 -codename1.arg.desktop.height=900 -codename1.arg.desktop.titleBar=native -codename1.arg.desktop.interactiveScrollbars=true diff --git a/scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/CodenameOneGUIBuilder.java b/scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/CodenameOneGUIBuilder.java index 113ff6259df..7ce5d7759bc 100644 --- a/scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/CodenameOneGUIBuilder.java +++ b/scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/CodenameOneGUIBuilder.java @@ -82,7 +82,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import com.codename1.annotations.buildhints.*; +@Build(nativeTheme = NativeThemeMode.MODERN) +@Desktop(height = 900, interactiveScrollbars = true, titleBar = DesktopTitleBar.NATIVE, width = 1440) public class CodenameOneGUIBuilder extends Lifecycle { private static CodenameOneGUIBuilder active; private ProjectBinding binding; diff --git a/scripts/hellocodenameone/common/codenameone_settings.properties b/scripts/hellocodenameone/common/codenameone_settings.properties index 1fbf5370aeb..aac7c5faf7b 100644 --- a/scripts/hellocodenameone/common/codenameone_settings.properties +++ b/scripts/hellocodenameone/common/codenameone_settings.properties @@ -7,15 +7,8 @@ codename1.arg.android.androidAuto.poi=true codename1.arg.android.health.privacyPolicyUrl=https\://www.codenameone.com/privacy-policy.html codename1.arg.android.health.read=steps,heart_rate codename1.arg.android.health.write=steps -codename1.arg.android.useAndroidX=true -codename1.arg.ios.applicationQueriesSchemes=cydia codename1.arg.ios.carplay.audio=true codename1.arg.ios.maps.provider=apple -codename1.arg.ios.newStorageLocation=true -codename1.arg.ios.NSCameraUsageDescription=Used by the CI smoke test to verify the com.codename1.camera native bridge compiles. The app never opens a camera session. -codename1.arg.ios.NSHealthShareUsageDescription=Used by the CI smoke test to verify the com.codename1.health native bridge compiles. The app never reads real health data. -codename1.arg.ios.NSHealthUpdateUsageDescription=Used by the CI smoke test to verify the com.codename1.health write path compiles. The app never writes real health data. -codename1.arg.ios.uiscene=true codename1.arg.java.version=17 codename1.cssTheme=true codename1.displayName=HelloCodenameOne diff --git a/scripts/hellocodenameone/common/src/main/kotlin/com/codenameone/examples/hellocodenameone/HelloCodenameOne.kt b/scripts/hellocodenameone/common/src/main/kotlin/com/codenameone/examples/hellocodenameone/HelloCodenameOne.kt index 5855a688185..fb53dc11160 100644 --- a/scripts/hellocodenameone/common/src/main/kotlin/com/codenameone/examples/hellocodenameone/HelloCodenameOne.kt +++ b/scripts/hellocodenameone/common/src/main/kotlin/com/codenameone/examples/hellocodenameone/HelloCodenameOne.kt @@ -38,7 +38,11 @@ import com.codename1.ui.Display import com.codenameone.examples.hellocodenameone.tests.Cn1ssDeviceRunner import com.codenameone.examples.hellocodenameone.tests.Cn1ssDeviceRunnerReporter import com.codenameone.examples.hellocodenameone.tests.KotlinUiTest +import com.codename1.annotations.buildhints.* +@Android(useAndroidX = true) +@Ios(applicationQueriesSchemes = ["cydia"], newStorageLocation = true, uiscene = true) +@IosPrivacy(cameraUsageDescription = "Used by the CI smoke test to verify the com.codename1.camera native bridge compiles. The app never opens a camera session.", healthShareUsageDescription = "Used by the CI smoke test to verify the com.codename1.health native bridge compiles. The app never reads real health data.", healthUpdateUsageDescription = "Used by the CI smoke test to verify the com.codename1.health write path compiles. The app never writes real health data.") open class HelloCodenameOne : Lifecycle() { override fun init(context: Any?) { super.init(context) diff --git a/scripts/initializr/common/src/main/resources/barebones-src.zip b/scripts/initializr/common/src/main/resources/barebones-src.zip index 6f000dc9a5194aabf4c97420dfbee7ffb6ec6adb..da205fa34873e76436d9de37f5f7b71a6bdf1184 100644 GIT binary patch literal 1435 zcmWIWW@h1H00H5A{}?a>O0WXyti-ZJ{Q#UwIAKbX^K)T9KGrkdul>xi~iE zxs{0p1z=4gKxqyJfh4imYYU|^f|(f@PO>pDsN&Y-Tj^L(;Fp-2st58;ZHRCFZ3}_D zzr%TIG@cw-y79ogS64b7@9@~RjalW`w}=auZYVhwa@0i#iv4|WJ>|)fo4Jdc6^ic7 zHm{NCo%(aKjlz=<&YEdcuWGDvi?WvG2}wQ4`oWQH>h_K~Tqc_i*}H@!Z4?y0Ec_xj zM9R6-^;mao$S#ekod05XDnyY)`JNWWv| z$A)=}PG8(?Ik~%=G3LOw5V>z&%2zHOX5_V!+|UrqJYC4E{rCFAMl7%Q`>2)1?pIN5 z{uArlw%K(*^LI9V^&+A9-?o~_?5+*)ylk>_`n%ZiNYAwQRGIc2?C@fXVv zZ@HxjVM=kgZcYoHdzbx9Krrv6#OXq}R{vy@b57WnzqGoS??HfA-JDHV{aPE?Y_@8w zyI;i1_etpU@@bKrGn|+1*}lT`_64~f*-31RDvd&ncdjg35^R;(rT1X5?>ggu8l`{q z8GYA8oGy@`Wx)1r`;jLC&MFzH68S;9jI-7oL@Vb-Q+Ku3xf;_xr@VXV%_T+5Tas^`;LWjBFmvXZ%oHTAwmIr19-4b@`tT z4;CdBnZ0U!`O|G((*4M}xjErCKZG6RFWM#1_i)y{@V6y`zGhOs@fp_*S-$Oj61V){ z?$Z}^E!?}lWS*;7Dzr&slkvUE52fY{pH=QUJ@pai$<3O0Y7>Fk~f`CF+NUa56BLZJC%^0mP*h+zgB?Ul|z~SVVvd z18{2RglSLC&n43cL1ZIRD-v@Ha#G1ON*tR}xs{0p1q2NQd6NSiI&8~Rj2;7hewLYm zK^3=wzLkyz1%8RSsd}K`gNI)7XN=IR4ff5yZNRhlcesF^rK4K%0Y7hPowHV3vM({j zHpsCbU6!0UN#lj`I>Rsf{rm2!9G&ng!Q)AF|Chxn6(8H*3vdPT#P2W?nwhoJ@Un{F zsR>^n*nD4Pp}?gTSll{4QXuE!iDQ?|FZ^DUJ=gu{v_*#&>8ivvxK8xuGE}YfKDfJE zz)^lepMo z-P^Ig@}9}rz$qrj_MWZd2??okhH; z?@{M9_3}KtFZ>06;NsIfM(KN^4C1EUlzeYf*;Tfp^5V^nA|Hc}7N&5_PqTdzs~%X` zUgxZ`{Z88Az8zhQH#ePT)jV3db7B0&9?@4Hu3ekpp`LD*QNRAt5fpM85-x9`v1 z9lK*~d>));(F-p#HN7cN{)Ea!tx|O!*S(ENDu%sD8rIQIUofNO;8ZP+zc@sJ%8e| Vij@s$5(6s`?gSc^0L=6Z3;^vFL8|cuy!d@9mo|?Ps)*u0qi%#`IRqZ=1PtSk3a;D|QXX3Luaz}cQlaj{$ z<*!DzHq767*1h@F4ISgN)7_cL+PBwjHQ^>{+;9nCW*=6p$XZPMy_8as^TEMnfAUxP z_uL;XwoA1K8jF&*HD!fgNgsC95X~6bB3vQoe@=)?aNs$*(e`-=2M8(fC4y=*2a{Zq zG^fj4Jxn#F@43Z$d-V><#mSK-hcmuJ+0V6VY+5$Cd`2#`%feqd<#_n$A2SVA?ELif z*`q>SXFYnGP3JW~bYGMTLoGQeh_~lTx4V&QSWv)=57x`}zU*C+iOQi5$5S+q>UjIL zopVbI)xOa-^_F&SaA|{rPxPDM_v2em9mu5bP7!pfc9jv`Bd~7Q`NX}tOl98ool+Lx z89|JR$Gf!Xy>4dT6RMr9RW27rzb&ed*Cut7ALQm8CO%hE_UK?ROLE-VLsi_R=(k}f zTb&j?(zM^?&SlOFxg?7J@NvCf#-^TDd*_j}Xdy%M89BX?MvMP*NApzf527oBJ`^na zsp;QVjrkL0l4HFM3Rf4JzYX5bt}Tw&Y?Z(}>_s1hNa0L$6%CE+++!D=@fHy#^xc2F zG@IQre67~0%4M^Ln)|%&t&SqXcbZ7oIq9vKlCs(wKrN85afg= z4XDam?&>k;v>>DV*BfVTGX6Cs!ZhKD5~X^uyKw7vTS^E`%Q-{SJx!L(?36D>M?->5 z$L6XemtJ1|BrC1DEz)Ii6KxB{+3l&HWeq)t9mkb)&jWVn!$iGnJ*mzE91(O>jyjd4 zwb);zKGJs~W$Bmbb+h}ZEl(~N{I&K%d@6}NN3|<64~#uKUyye;Y*|k!%4H-He#xdD z2pGTxzpMWI`UZ_uPTy}>r}V0{)Nv^);_1Y%HM`yQ-Gpx)v}~KOnkq_)NLe>mL)CK# zWq;0#JjL5uZbtsNX(PKKwScSQcuHoE(k(~-7#dE}l%_H6X<+Jk%V1`F>XTH!^)oUr zmoC1uJmIpuU)1#QiQ&p5TS&|(QG8{5Rxt6^94uS-{AI?ZtcoyZGhz1KKFPa$eDT}+ zdRH6Y$C+y$dFPQY=#kxwUpb4eAJ;0p<48Q7w3Pm2q3Jp7C02q3ydQz1BJTU%*tcnN zU;7JBe;b--&@k?#2tMw0Oq+CI)X<}l?$Go6Av{T7NvuzV9Bh|xU7KwpzW7V~<#;8+bl|1oH+4`7IqD7y_}8nRL?N=;gu zH{T53d~f#rk!gOSMZq9{e$0^XVO@QBD_=N}x1BO-Ub$zjxn2B8`u1Z1AKMf8_oUa< zx^f)E{Lb{&hHu%cxS63&AC#JLc&L}>K{_#iFYQpy*rAs>J_`DFfv3~p)mEp586&B> z&bxYi`fMfWSg^lZ+1L1^%&Woh<7GY4!#zXg{NS|Tw1sAA5Z!W;2_EM0_#mFM1U?CTn zqID{8go}|4tH6kIoD|gVz!c$CR{^yHqqqJCh`{C!OvoVyTOH<2^ZptO61xEz?P0;FZmLH=P>VmS3*j;XGbgCgkDgJHiSIMM^8VQmiAgT*>|HTH{Gx+Gj}jw~!Ld%T5x(xlEc43XbT80D7t5ex zACQ7?o&!}>wHylbfHtH(!))91VcX&=p+_IsB(Rc-@FWiqM2aiH-$@8{c^Esl5__C-SFm(Vk;lP5e1HckZWI>_lzy^KDg3ix@t-=xu{LFAi UTfvpbftX@l6OSNS?Epjn0rK{?1poj5 delta 2227 zcmZuy2|Scr8-M3L!_$EV& zHs)$Ykr|A2w9NgA`fl;b&6ImfSM|NP_x`@^yub6F-|so+Jm-J@&-47x5Lb!MRch2F z66CCp%I$mgjCw{%9zo7(BM1Rmfka0|S|mqC`0QMYfGzK154&MKA(@2W@W0{^1dm|t zBwZ{&^iFkl!mw&M_?lDJOTY0RN@0hb zwOBiwoiyPk-RU;AKki3WF*mn2@mPee`^)chCv9g>tzcfHZ=rt+wZMo}lRJ2z5W_W|OO$#AW>|<*${!`P;L* zE?p~sZ!}YD6@BTN=D5O&^MT3*&TN~tu0^emXDE($FV(g1*q=|niHPZwR920ideqjl zmzg#tzbPyKlM?=<bDVVf|@Fj;g#d2VB-nJHt*^?v=^8WR`lT5u*VMe;?= z$x-nn%i+=E;ydgRF22|GpMKjq4WC4gt8fgAb8K0&OIB?a*Q`9)Y>>I?)ii!^WmRr^ z{WwcZ%)frf;HsDCj>xDX#LKK>MzUPt<1HHgm+%zzz_j7J=UT$6jdhhr25F9#gO+=D zSWSP4CaX5s7+RaBXiL*;1Kd6K|HI+%LuUMYD?jfmHx2UN#Tsk>eV1C|FSV= zf7CfE{P^;UjPObOYiNH-eQIn>Olqo!1yL;eoSDG~@?aMwi>nFBTGtB+NTYi5wHl1hO8#+qd z&9wdTYrM11Ykr+pc45jv2X1hT^&RH;r*ws|w95>`I#(0#M)>ONk$^N zGun52RG%1n%6{eMTJh_lTV-*Z#u($vo%NUQ3qFk>ikz6-8$$JeB`(C zWk=_V$!6td8yq^KthPg8HfO2EQx9oG5sT^cZBp6MXUcxhnmuN1M;+=@;*=F+@}!Uv z+RVVcV#RA;p2#K+WNlQUl*AVo^Q+t1%B81Ga(umaoLDU=$nTGzoB8dQ{taM5>S$IrhMpU=n-6wn4crx`IW#fBT)noDnKxS9jd4f*<7H*t|pNMDRn?o zvmP}j3M{I@4pboKf-5K`y<*0HUiJQLm{uYYVT^=i8WeT`Q_{RWHi2RBeNa41>jo>J zT{8|3b%lV4p2R^@Ay|V};h?_|Y#?mK*vXzoc4jQL6t-rWeqV2@9L%e`I9Jeme=ai@-W! z34(^IG{E z&NVnBEGlju%34%~2YY&f6~TtLXzUjPEA#*lZWaSa^db+Q5Mu|5d9X{2Eq1Jjb7HU_ z_2R>IePA7$$cKmefR4d`JV@AGjsIX_k-XGA081`|Rj{`Yn4-H1;cOq+fHDi=+J3MJ z2}Xuu5tQ`($jsBMw(LzO*29qUZjS{H{ z87dVmB3ldk?!7ZIrf>RHbKmDV&pG$pcgAyG%jsOn?>Rv=9*pn?78D8<5fFLkaD-n# zq#F42Eg%Y@z(b}Op;XCt0Q8rRDESVpq|QlA^E-4<4V2==2%`m2C{W4_BSgLuhpsd% zFcR<;ECapYNJg+^WFtO|hmpLZMp*&J%rR`_B}MWQmVBkUO6WDhuw?-vj3`vFPqdF( zrZ77*R5bD)E+kW!jt2!6NMiV)cS6WJ5k!Gb9J!Fh#{!}-F3Ic^6%?Wh2NH&X3JkZT zFTW?9s_278b`)w-7lo3i@EaJIaoz6jk;9w$6Bf%%mV0mR%5B&<`Lxwe=hQ}np|11W z&f`13e2J0dKF_%e#d_TNW#ymv9>6O7hJsBs-fqsDXY65WWQ*SYnTbL1qn5&&dligx zh2PRMj?euVuVgqZ#S_(TWv_0wHD)8<8%rL2@!7OpEtU44c3OlO*zrEM9jWNWZL1GF z7Zqpj_>IjyzV9) z1CP>`oW_+1%D828U&cmT@@q-~e7$~;s&*dB7L?QyI;SP{eTELpDbFRftJPLW!?s&H z%g_D(#9lnBT+TJF8f!}~4y#l~TikxjshmC!mI&(`Y5beaHoa}Nx>2OO@%o9ay4&&? z6z#`7%(lHSF}TXhC!pCaPgh0XeZS>e*R*8%E$RI2y?5pGh2nh^r7Yd1mn|)-GH&Ni z@hog>^0lz6-P36xevi}Vcvjvu02Sure%R#ti0R|Ri;DDTF^QMkc884(`wMSf#+BZV zx!I|ne5p(K1TgYcZ%=Hi)wMz0^k9raXX?VV=eO9jJ@ZrBz88?b4b-)q+h-C|$j$Uh zEYjf^|F%cy3G1Cc{QFNnc5a;6F!A}&@RfyWnJkvXr^79w2T&`hjGgi>^Tzi(4;PW- zT?UqmN%{1j#MGirSqWY-+VF4(^Vu6Yd)R9mJ~)o#aT&{*T@=n$+R%^}+bJhd zBIW3gNjO_?2w<_HGMR@^UweKE9`BJ+bUIsqVFDHF};^M~K9dpm}8b_4* z^Cq5O-nY-av*x&oMj>E9)PH5f6&NRiOVd>zVqVT5{0ub1Ha&XLxy3q$cSqu-?s1P_ zVtRwqj?c;^V~tKq3GSJ0zZct4UCf{&`0NsI(p^Wp%9J;O;T%_vb7KVuC!1%T`xf)> ztE4b5mJN%LTI%fFQe46EQMBCai7>xBq%i+!owR2`#n=m@g|xz4G52=v4z*wmV->Qx=R$yG)m%>rW?RH0S*$ zirZG>X7d5rqZ8)#3c7{U5;BqfcfG0;F6R)0_n;$3EowypL+=RP$GjPCgs@wRmGtLv zXE&D9?WN!AJD=s2q$qpgbjYD0$GD_!MoVm1ZAO$izFy8!wj}W2LsbpEMmZDxC#O~d zI0~&sk{{?C?jV9iwx6-LF4>L>3&p9c$}I2)ikEG7+hluSDK!37!ss0?5kQKR%*akB zx*&5Ws!LGPwQTls>R`s0(-9|Zlt`V00B$Vgq=yMAWsvQM_pR*#y3$t{nU*}}%7X?@ zdX=2!YfRq0d$aaaskltZon6NDa?*=#K#XBxb+&4(?g^JuTRl(gPM z+~81)NT7AM(*=`glNk~3#Pr>)nm_KwAJ+OZ;?X}ma*5+>C}9z>d;G!a#p1Ph>LJyn zy*Bzi3@>%dYumAWLleq?SkR0q^BCajBFns zpwUWVHkajFB{<)*nagWcYx^%eb~LJaEPk2Ce|~SG{%@6$9dT$Ywu6b|3D=JteHp~= zZo^kyS2gc*#9^3$`G73nhf90rW}}HlF$2M*ChqD{%om?V7k81Y;b)0IE-O6<+3EXW z6HZk6^L!wI!{)l1-gHPuqa%0Ze^TG4{ES z*QBciS2V6;(1YbQl8!vvAwkKf`vzzUt}PE=xk%- zfRGK(TTQtk?gefqV0^!`%s|Vg02T8)DygqCW#<50`#5C|tahvOA@x;}S{$aG&$)oY-)TBr;88_#O9h(doTPTAj-= zYc1Pq25T43#W@!bu*PwRnA79UN=7ke1?+c*zVCH>KXp|4=9~|EUbp>{Mtgy3N%H~! zEyK58j~0lP*bxGaDt57MzHWFYwZK=Ht+FilBCfpc5_A9ChL5V88p>%O9Z$S6G}H@d z?CFs2@meZv@f7YEX9|oQ@!#yrg39n}hzXDQwba)6_?X}4*H??nO&aMVFJD-q!wDXp zhQ8}CI$x?(ilRHKE52JkG>YyCO?WlWxAgnO<*`3k6R@r|m`~>AvzL43!9yjBdUX=J z!;5lo+p`tUiVk?^9VQ^~i( z2p*04`Vp%5QMIdKT5Tiyj#f6$`)NFMK4>npgWj-V`j4xOngmbHY954v0*_aFAYz}cgH zxXSY$Lq?#YDbFdzkMXe`0jSOd2iDcr${LSr>HDk{3C1sPB^gMyE_lD()7u;v z_%v5zJ0~tI?M?6Uow?or?KRH3xj_JrIlm=3&uGhqE6+O!&q0PG^LJ}rzuT32bR{P6 zqUiOD&+QhL{J+gy^)8VT_q7nRDel{q`)hD?;>G)luQ|hd;~(hST!cvMLasG4jRu}? zfMF*t?t2|6VhPsy-F=2zB({)@(L!#a(|?E`3-j=u*(A3e{aCT9uR6Y53LnbpLU~A7dL<5=`c&5QmB)OmPsDepq!Y6h zN_mmG3d$p2r%k)kZ!?+Pt>qnQJfk6UAUZ_Z?uSuW>;*Gv*1_4u7EhUU@O41XD8~_3 z(IE312mI@IxlQJd(1?2n&mxdP}$|FkdXapA~Og2O8!)mqF?Ms#rxM)RqG{QT;cUNbw$3=%46b7>tW|;;ent4 zQu*Sxh$8VCzxKqPlXq)`3_1>m1Ru&&>2X-ux^S*MY`@|{r;OMQwRpek7>Sg4OXTM**8~xz%5mHlExP^dhXu%7VupG#RI@USCvd(6v03RWp>4 zSFnq)Wl)Pn^-Q@ymguwnuJ4=jrmP=#T$kzNj>6zi7G%df#E&h?X0km4v=iL8?`hac z6GF23?&jDi8RFtp=1NfPzsew7s9~z8_V#w(`7Xll*R|CxwJ? zXit)pflR0I&-5FjrKsOe6867oZmT*~kAB_!i#@jd+6Rw9-SqTlpTC?i?itztW-9h7 zcy_i=!~IRDZ!{nHIZ*h^EFm>S&hdU~`KJE;_0KQs*p2y0oSAl#w79x3#pjPwFU=;7 zdIO<4vjM)xtU{XIEShcJux4#4elmJ2>ZJ1TGaqlx3!OPvV)fv|i8`waKkfb)Mnb;y zTq%2w>&5bT7x6xqN!7Y>*KjxY?mUqnKiZDJFMnb`=@``BYZSyv*!Hu_ydAYNf;L_u zkDqk1lvxj&M@1cM&=_85q+~+rhT40mN~U$#FrZM&JSddj8Vldg!%JY`-N%58lJFdh z&lct-vkLsXIf+5So`%v?OTA(kLBfzp>e>=MZ7UCfxb^p%I(~3F z4}r-#lpd}?8Q)-!jK<2Kg8~MFXK~;n=r}w@*vjB`NvIB=-7-k&)`U-P#fY#v=p}{W zCoFn3Qh4vBFd_sY|1bnq2E(K=5`^jfofPzsG)9OZd{78Us1BZy!SLhtGvx{O5g?g? z$3+VfDx)(P$rXhr@DQ#f9Hoef%VPK-x(Fd7Ih7)KoxCJZ$W2Y4EGfuA1sy)^N3IXg zl*v!f&%8&G7t9tVIAlLTu8`Up!5(=G7vXr03%LpKz4H;Y^ZF=iFBPDQ_g$+;E+s)u z5rBbai{MoI4F>3;0|RK+=#aMvLcr0oCqd+HKKc2Bl3Ex>uoeq7 zmb;Rj3E2g3BnxP$gkd9u*PBy#@EV@f%uGPH{9yh|V*nMEp*!8x4N^k$gQ3v7%8;Bz ze*`5IUc-;Q<|b?y30hNQz+ZXCM|k?~I?^L@Z6H<^y3;2U>1)L?fn}=DCaU;WL>-#2 zuz_%EL6w!NkR<>RAga*;7RX~;)lYQ8Vo=02Vffh=Ayz zfFsC>4Dlxqu(*~}kZ2(SxUF3?fC`!z4&pZ{z-p~)44@|#5Fut`fz@iE_VN+WXaIfG zrC!y-2or0KfJ4-BPysx|1Pef%nwhVSVJCjJ2WHu+>KE9A;Uuc>1>RCURZ!O-;3oz{ z|4=lcrVA7MgMky&H+gO|RB}lK;6U}XpeMr!s>A`zM8`P5nF1Wwfm*bj40x;&SwSXU zD7x$n;7Tp2nhllhnGO72D~5&3KEgjBVqG)KE&__wVJigyClPxMsG%f4wjoO~)I8H- zplMBu0gTs&vN~1(oD?Q}_y*po0YoSr83owD0|rn>#A*S~)lbMMzzTjcz;J-c4}gxp zL{@OWA!Y-p-VKNm>l*-WYWB~E02@)N8E~dv^oDW~yV`(I$|96ojF{C4SW}Zcj4>OC zkft2<;-E2<99rZhHuVC`)QHO#=zb(#0OZd9r^qf z!Tt)MV5|qikkeQMlUWrL&cNSIvG`aa2N!BG<669J4k2U!h({=1RrO9nRoJvOF( zuKyk$Q-|)*MKtlyQ8GEDETv2oQjMb}49kIBLNqBakOA0ifSI(QjvW#O`woypm?qL} zCmDn+2$)F=dN|SHpDD^CZUkf#p$WD0fKeR=^6lYws0yxYLz6dI8FDHhizrQOvp@Mx zVABGo)1p8S8HN3e3U&8jqeb^Lt&9PKLUl2rP@5?2Avc~glpF?o957ytCS_0r8HMf6 zf8sQt+7SeVjSrYW3;M^ALC6FBzm3n92*VQO-$;Z=&?xVwMpx|;I73VGJ3%D^Td38x zhPbV7Yy0UnBEH;Be3cjPwVqd(xsHcH>=$@eil)4#>@^w)Te4NX@crxcj^t7iVY9YM zEC^XoJbi_V2-`SNU4|y<6fKs~WA_ z3QeU{p^!IREp{boeX%iwH694NM$kre$TP!2MjLcdr-9w{C@^ff!691M&y)iHW4=K* z4H~KctPrja*iVZn*i%$sLk`+&(gfagp}?>;|L1dV|8Z8aniYlmpov0ht^1sx-HUWj z8?@7+QOpjeD8fD-d`1hKhf`qK(Stj*X`(M4qrkAY|EHc)nO^VOA^%|v{lL>+S5MO^ zN*rwe!7ZC;WM5@cV0aJ!8);!IG}}UZQ4ciQOcOYnM+t<71F)JF4lVk-OUYxx>Q>22 zrr9bhWoXbx2crvC=+LCV-$yjC$OHkZ>C(V*O_U1YSpqDfh27c_Sn=Pf0#wqYk!t9s zNWt^PKh1T?HhOpiYHkYDT$6Rpz1xpGY&j4fK|m#a8ribf6j^u}A%AzRH<)wdXt2Tv zqePGRZ18RkO>Yd|Ljoi~37J&>sY}uv?Nz$$&A38_#JHMp`$hw$`|@m0D0smY>*2;{SOIv1+D-9 delta 13701 zcmb7~c|26@`^U#QV^4P3ce0MH>}4q>N-0!C3rVYNAu^UMNtTp@h#sOMTV-jpW+_ob z3n|o7c29~T`OTRbW1R0C(@!t2{<+@Q^|`NmIp=(CVV}8X&v8Rznt-qzBSsW+WdEuC zYPL4481PL=!r^Yhua6%)h5`G70fWKvVK5kCs3PlpsI&WV`r#liMidGO0Qf}dWfo;1 z1`017*sB2ugW{x|5_-g(U9{D1vjmB%SunaMw(i+$g{#QLVlY1J7|cpC4qep(SV`sJ z9F7zJGvcybEua|73n#b~Wh`mE41?j;CM8JV#wy?`^$+|n``p37t4muTXsXb7w!~Yx zJt@)q&|s;9*+sGA2RF$yJ$E^E%21tkQ8w^&^{#BpOHCDU?4L?}02={N697M;`=Z)2F#gmWC* z*nk7SR#|V>@@WlR@t^)WO+l+oc}63#O(!?kzt8J+cWe`nT^kbsjpe*~chq;~8|^c% zuf(5ssdI_bMAbR zvq$P!6U^0;x1M+{&$4^pTib! z@0kSu2*JbEoLvkZ`q{1?=5Hj#*|~)VOy$NZS_98Am_$UM#$&3&KM#hPF(;l_c0_imBsG|z*0w#@$afK39fe(+_*Aj#{$}YYljpM++&hx zoayxI7T#=>1{Uu&m)tj{64Cce-B_r~E}HGm2Aw@V4I{qBA5M1-P31^L*|2!Oyt4d0 zZxl02jDXO+dM)Foan1Y6^-fZ@N)748GB3Uj~c(^*7UQ=H7IYfRrdL3nZ5Fm7j4`2sSNS4LPYU$CQ@IrLFMEl){O{gRF8Ay!oZ4`VVPl_J zEjXO{6R_*Tey-j4s|wf?yfewp{$$`WU8T-XQ&ETWUn$fyRhyVUGSJ`1oh0%zXXwuL zSEGB(%Dyl&b2)5JN$11iEec(@f)n1mw@zL3VmNnT!}~N~r8Kz0`*65=j^WXo$(;N0?)5LirS4m<`($A=#8&%!nn9mI?yg|8R`A%P z?8*?iNv;juk48t_B1;|Z&gQ6RYJGh44-k3?vJS>+8lG&}{LDP0_Rc>1wE39g=`5Y$ zoVQaCU$_c6#5Z@IF;C+^?%`u!$nmqOYqWBWv8rTq|JjfGJ6A$n3h_TUcpuAOc9PFn z&hq;}?wju}wR}USPsa9_YzlZ7Y`x*3x#G-!yxi7YHatBRtYMB^8MhuNr|||!YYDsA z$@V0(O|_Zl6)A zKb!J6=JqdalyQrPU4WtUkym?cS+kj7yK0Uv(0DK4W6PXd;x#2 z1LHCIYLs1}aPmfF%%frv)!w;-EbVtg@9h*Haq>*=%zwF2{b-e-^Wz;B1x0L{8=In@ zNNkQ?Ze#LA^8C19KBqjB-Pt7Ftx-mjb#=G1duw$;L84C6{0_TyvE9a zcUSTx_Tqz)-i{j|(ogBg4|522)#68Q6m#-)UV7SkXV>@hJ()WGuSdG8w&S}Qh6nuK zyb(^Ac^UFERQXY_!nvMwE9>uexmpo&E?H@Qll^g*>cTU^M>y5oCE0|VZhUA>%NJ0Y zkjIGdJ6A?r?E(WGt^nqG+UkvcjXi85&n0Jv)Jh^{Ma(y5EH6D<@Ny$Vro})v-rL#c zQnR*$80(1~-4EFV+H*4j4n;1e-JjMw)HsDI1&eOc_7vL_ptC)@-Ze_B!pqfhShS+( z>)zuW7G0HN4L$W{7~HRP-3Z}R>s(^-@*VYlY2B?!v#R;Gl~wJx=H4DIvM#hY=t|z| z`hf4L^V;V!mxViQ6`=&43yoHB9i8}_X%%a;oK|-{)ol3kZAV1;^$WRzDn|N6V@*+g z9k&t{PJfq9J+ZQ@_1ZDqrZb5_MshnY5B`a`z#pJ+{$Bwp{(*@BT-BB;@tK`$_Ul@h zdH?jd%w_&^viT5tpZQ6lOT?xrFjvEe|h?#wyx_a-UKaMj#$-79`bOGvHPQ9x?$7F_uHBi@(#IG-3)GhJ!&NK z>3J4DBv!8(tMM+c-PB^gw9*^h;$!vphqYIIjVm4r>M@-sA4CQzE}7QbV^8e7biA)A0iTw6$S>!qfXZP6=@6>+1U#--&P ziRDZ$2leH0yOtOJ^qb1co4u%6w@QRVf7@nRiFSMd4vf`E4ZO(pAYWuK>1VRqKw5>w zx|koYe|chxti@kc*VZ@^;a9DBG*mr9;lFhnSA_@HPm!i zRaC71Pr4TWKo!i>`E$X2w7g+Z*tBL?<4}Wy%*VIoUuN2KXAVi9QRetF`>k!6s^l-< zODqX$c>jU%Q{f45H&0gdLC}bfk{^b_=Si5sqfB4Bi?^TdvKn^&^+fi#S~l}F&a6Vo zqh>#zSlI6kAD>!RIR~g*eyT0+u^^4sFLuTI^gI{uK z^F%}+>*~(UT+1qP=X_~hMu&TMmRCxX_mes?#nbBrdD9Wsvi}_J0R!|`dv3ar-{rj7u{+7=mVtY9a={~P+|BbMV;g-| zGD81M*6^KUPhZ{N^3;Ua*Iv*4&6G@qLtOXj{<^ACAMwgN_p9*E#{&I+?KlVRw)7M>U@4mM^mXqvs?ENnOf(xfAMNBIVYJa}hS=-`* z=es(0m)S2Rr2ec}lkirdB&qe8>MzFDxU7=^+!TgmI-Nd>vx2W5zkRmXeZ5p0M{>1q zT{~m8T;&Dkxt85)x0ivRd&kY!-F9{PS~t=f8)M2MGkj3e{czFEXngfm35zSOiM(z6 z-vtCXb|{89++ulL8`;DK8u#-CW;}P}OXk>U3b8^qx_+Ni%JhuG)(qn{CAE@OrJpSS zrup8pw~W7oJyTO9NO4zvuoP5Yns>?O?S;ziU2y`LwcDO>3XlKr`@MRH=efB&$!xD9 zlD&Mo7}wYDbu;#_{HooB*UBys%aS|P2h6ruzP@Cl)m!@^$%(zNJ0P+hvuS)%fGL8j z_)OH3(uRxdQ9DZhN!^yb|8}_g70qK?KTHP*Wh8ux58TMZs#T?NhqJBU+v7Iyg(a>i zC|o@MRzgmfP+ZS)}vY zO{TWyd*71^&JBJ^EE+lK%={^s&3m5CxR*o}Io#LO#BDxSgRR;0kv(Pg?dHnB7_r^4 zLJgY+cL=U9OE|5}HsoflC2}+{Y_~f1hS$rRy;F~w0|`4)HP({2w32URD-@sten zT}ip$Z>-|~8giKZP~5k~NE-~(?phn zhxYPd$scR*N0Gz-e%O=^ZvYN4k-paCq0?LDzwOY%W48b=!1-`hUaY{vCl{^kSFC~e zl<*8&fO{c)4-GLzwm=C*%rq~SDx6mK)IESHc3zAVA9lq;c3R=W`++)&m_|N&oe??+ zU@6(v__52E&c6LH@QxB5&yVF=I^6jLAWaF+_XGr&4zKeBA}Qfc0$ARq!^3@n8S+r| zmX5q10GwbX^w1*&Q2u|cHs&Mgoh2X!!^ncc7!g(*0XJSKMB@v(tT+T{fhEC(puBME zg+?p9G8~YBmjW?-pCDFzA^UzBD@P>;$b4~r2tg2XodHr08Nza?dgEfLUvlC7$!u_PXgOa#4^t}ilq>sT1d3QMG66b%6PwtQ12NU1Aqu(M9RkR0Fe|$PNG=; zB?k>Ns%4+c06z-zOqAZBGadlWi>G^y7##+#v$D*+3OG-xlP881UC>6uGJ**6CsO8E z2NY8n;;azX7S(>G)i=9FU?+Jd)u8v!sSiF{;iJ!iHn>FfOJMzyipm() zVx*L@iqI$)qm+ z!AqLhO|caq)loq!Tzdt0j?$TO87$dqg`eBB!so=mTuOMeEJ){J_D&YWvCoUase@Ec zRvO#B%uF3z4<9N-?S(oZ)sCn2Ag3YTC|z^Xxo zCg8HAyZOKboT7~PjXB7(5Ke0VgXW+;CH%ZRJu&`UL37F~9+t;aJv3;I7uZGB{8lHB z&QN=tz&3L8jTU6nN<4l9bcbaVnxeZ9N$Y?~_5j5x6WSdJQf(w!i3b9~36A+08dRX( zrnJI&&VzlFgJZKIy?v*i01Cje2^&cXs!*iY?O+HDr>rjJ40`R;&j7bkb~Ry}(mBQI zazQ)FTpAaFR1ZX2D`iI!xQCpb&YRUhIk=l5J71aJ;Tuo|&QN-oR!_Z$XzhpMdQfpb zdr}KXHAq^jxmv&q${-0xHPvH}R&w^&U=>A+xhnMp(a2u<9^`_PbAJYv7FHpRM-pW4 z8H8_!;6R8GNBw$FYt1Hp2D#uzT`wb68EXAXeP+=Jhu(h$8|IUbPk~tZt)4CiJ#p|& z809%hi~BPLij_?dfIP%!yc(gFo*MPBPJ=01Hv-y`!?hQNOe^xmICuh%B#c=Znp2}U z=78^@1vy*^B8-CSoTinXpk1C4zIBFrYtRaJngPWq;W>Zkh2Q%FHdDgkmO@1UmT}4P zLIg!>WuE}-Z-6v&YnBWz6KBGzQ%d-=((C(KR;&dG^=klvN^FFyOV5K|?mnK*2favl zm+-@n#X&aC zLP(+Tg(o3YVxcjpp)#aU*}n)?B8Nhm0RZz~#H*3w)#--9y(7q#gYqWXmm^wZe94IwR}~~&M#Dc`m=P2BfAY;WBkATEF-H&q5!GVFP(w!Z5NW2C06BRV zfuWFz79b#KYqJz0vWf|03=Bajb#UMa%07plLkb%oX2E` zoF);(8}0Q(bu_STmJEP62;bzB?!*^gX;Y^QWg-fIiny_?=qiZHU)7S35I~N`_?+?AiVGG|tQ!j%+0SF;+Vp24lQv8fT)Z za>AY-`iOc(5#4wgN5vAS0yg;mTGZUmd&)(GwIxM3CpRn-^&*ifF>C;$i)s)ijRn1I7Jen7ko%!VLuTan?Yj9 zH6#r7711$!DMYmo&G0Y{>5VWS3od@WXz3u8E6OE&NWpF+dQBB+M9tK03d>G(9qCnP z;6YS(=qF_`;sN>53(p`6+kS`T zqz8|yfr6aWZ@c#y2yf4@e+|2q^k@$q1ih1$Ov5H7J=#eRLGNQH(-cn=y=BMcu;Pn^ zhx0Nln44xxzq>BH_DBCHfYuUjeMPu280|#|-78_T7})(p*P$nm&=D#{=3pBXol8Y> zB1&Wq_Cx8lF2M=WItdLj4cnvWRozx1)S9j#az=mMut%%?w*!Q~8nR|r2X7^-h8i5yD_LTcaY!yEj9d?PWB+<$jh1PgTtj%3R20HsbQewR zni!%EJ#^{z$_VMhiDU_|Z;Q@VB00lUG6x&D=$yO?qTa)6Bo20R>CJ0#Ct_Y3Zjp<^ z#x8o%No3K_MPv?kc+oldm4aJw(JRG<3I?Kyiw+g2B1U+Vj1YZabWQ+=;J6<#EEvG( zTp*IeJtj$nO;oHjwG~WoduaG6P%kn=Ni_rHF>eRco0O1o#H2VpA=29Dl5^D%Lltcz zN+#LF=p2_if~#y^7%JTd=CT=tQ2iHV8n%zot9Bu)-fkyzu#b$+nP?!?w!U6aOEQ$v z;cH0PqKmj1)}SNonuvO@ddT%)cNv|7SGhjhqE#N<$FRs@roC`TMqGl*{A&ookt29` zEqx3`$9d_3y2}?8RO7``6{Ogiv{ox|QwlDkeR;7&3wr62+>71GCK4n;2a;J-Ns5nH zNtO<@*i;E3LqvmmNpk+Zh~x?PkvR1w5##}7$xl*9G_C27xJ6?tm?vTT8i)QG#z=VS U!e9;%{=LLuFaiREFJR370p4L*g#Z8m diff --git a/scripts/initializr/common/src/main/resources/kotlin-src.zip b/scripts/initializr/common/src/main/resources/kotlin-src.zip index 32c52cdb23f951135e2fe1da62acbf084a784591..62c4b0d91ebf286b04879864fe10fdc228030322 100644 GIT binary patch literal 1563 zcmWIWW@h1H00FH${}?a>O0Waz?EI3P%sl-7oQk*+ijwnl@hB8VRhU|lm|KvOibsPa zb`80ei3J5x)!DsdqijNQ3BT(`3GXeYCo(K%NZwqn_vya3*Qeu2lbNm_ zoYvO=l(WK)^8o-t;;7^c{{3F#Xk1;vUc}Wch*}~nw%3U zIepQt8d=%fGd6@3Z$7w4S7%>eR?n`yAf@lieqPJ)zHNSX|77p)rqe&lcLeOuJRkM!rquo?&fjgrLWY%2AACQE1b(`}W_7pscGF|GHv(Bv z-f?-eOkM9wXDnj)cfp$X*3=IUC#9BKIGmq)ak<+eDc!e@>~EZ%uV2>gm?7leDch=Ug-E`K|t>JXUt@lNG6u4MtUC2XTkH*1KPZesGXNc@vqS!MrBil=~ zVl}s)QW1~rK>-bqdi9&ftGjj{{u{jLKzWkiU!Mc{6P%hKuT$TV;QOOx;p)T7qipV- zv(t6Ic|7yHg}pmp`uYX=hIZfiZ-r^ zeJ#MAB=a)L>*R0G*FqaJD}VjcTg$=Mde!jIqPbQ3Mdq%1up{e}V9n_U`CA*!+Olt$ z@Hst}sNQn&@Z_Vviqvij{yaLj@w`Y*rD5A+)$m+9soM7kHv9a&lyv@IYwgpL0{e&B zi%TM(rR$|{yS%XBm#B&P9@EPD1Lg;`Euy{UAKd+YuT{Ik(tkpSi+AV72U~?J4&Dif z{rqC>i_Y%&53!aXqwh%{*3Yhfeej?t%W?m`>g~!WFQ0l67E|MPdN-@$-;Ao72l3Y0COKx@1rJas5C|~5bp+AyVhFb;P(cI%AWdkc06yD51rtJ}ACL*P z4OE^XiYeSSg9<7L0NGp*WMVM@R&0Tc!Ci2Hj9~=gC5_wg8G~Gm;qw|O{2>73GA9-k Ym!ZZ6E3oKfU|<8nKA;22fl3(|08`W^mH+?% literal 1507 zcmWIWW@h1H00FH${}?a>O0YA?Fl6VKK{oO5@f+C#qLdW0l{rO?G#Kiw1)-7{F+x(p*J7;FK z8hSdN+VGWKQmmn57Brd z&$D`6(~Sk+^kzSu7oq>?c<3q--Rq6jhy7O{HuF?l9LS`6Bjm{fmCg?uGH(JFi^_4| z*!Cf}j)(EPRHMny3w(b!-M@UQ`th>Kou3c=vJ=kcsWz2#Iw@Aunvj)!Bk{~()tu}} ztS@CV9BsNPGY0habwKjfMye5Zh zujfmFdBPms(p#o+wQRbUkS)8zRxDguC4?nk@m`+Q4%LbT?e2pTzh0lbRbufcwjrn} zy*!|7_JZE!?muV72dZ@`?VS*l@cgjHt25DoGqx9e{=j3=%I$pr@apopDkU5C`#hNW zH0*{%vMkT$gR?BPMfGwI$2)({zVdbDK4k-m?~Hz{=O4(iy{)tF&e<^gXWP4f7V+et zdRQOwSgX!wx7zoU4^wqa7p`k&S3h~P>D}=cDYX-yCvu1J$OW_|I(?{j`hNPum90~j z_xu*eojJr&(@k=IN@^Z3q2%WgO52P~a?H3gtOPXc3NXBN1To>+mlcwIF|sah!?+oc z4Fj15H4KuKNjFd!#lSXH0}P48DxrU|1H%XFRS94haZgerH(Hs0O5v0s`i4 ti1Db|9iLU$BTyX0Cvm{i1<5MZ6oSieRyLqB8Q6eOj){R`J` is forwarded to the build server. Note that +`java.version` stays here on purpose -- it picks the toolchain that compiles the app, +so it is resolved before any of the app's own classes exist. + +Most other build hints are better written as annotations on the main class, where the +compiler checks them: + +```java +@Ios(includePush = false, deploymentTarget = "14.0", teamId = "ABCDEF1234") +@Android(xpermissions = "...") +public class MyAppName extends Lifecycle { +} ``` -Anything prefixed `codename1.arg..` is forwarded to the build server. See [`build-hints.md`](build-hints.md) for the curated index of build hints. The complete reference is in the Codename One Developer Guide at . +Declaring the same hint in both places fails the build. See +[`build-hints.md`](build-hints.md) for which hints have an annotation and which are +still set in the properties file. ## Layout invariants diff --git a/scripts/initializr/common/src/main/resources/skill/references/build-hints.md b/scripts/initializr/common/src/main/resources/skill/references/build-hints.md index 3ed3c1b6580..136d14fa16c 100644 --- a/scripts/initializr/common/src/main/resources/skill/references/build-hints.md +++ b/scripts/initializr/common/src/main/resources/skill/references/build-hints.md @@ -1,72 +1,185 @@ # Build Hints Reference -Build hints are key/value pairs in `common/codenameone_settings.properties` that are forwarded to the Codename One build server. Every key starts with `codename1.arg.` (the build server strips that prefix). They control native platform behaviour that cannot be expressed in Java/CSS: permissions, frameworks, splash screens, signing, platform SDK versions, etc. +Build hints control native platform behaviour that cannot be expressed in Java or CSS: permissions, frameworks, plist entries, signing, SDK versions. There are two ways to set one, and you should prefer the first. -This file is a curated index of the most commonly needed hints. The complete authoritative reference is in the Codename One Developer Guide: +## 1. Annotations on the main class (preferred) -- — full guide -- — editing build hints from the simulator's *Build Hints* menu -- — variable substitution syntax for hints +Most commonly used hints have a typed annotation in `com.codename1.annotations.buildhints`. Put them on the class named by `codename1.mainName`: -When in doubt, search the developer guide for the exact key name — there are hundreds of hints and only the ones you actually need are listed here. +```java +import com.codename1.annotations.buildhints.*; + +@Ios(newStorageLocation = true, deploymentTarget = "14.0", pods = {"Firebase/Core"}) +@Android(minSdkVersion = 24, useAndroidX = true) +@Desktop(titleBar = DesktopTitleBar.NATIVE) +public class MyApplication extends Lifecycle { +} +``` + +**Use this form whenever the hint appears in the generated table below.** The compiler checks it: a misspelled name is an unknown symbol, a wrong value type is a type error, and a value outside a hint's supported set is an unknown enum constant. An attribute you do not set is not written at all, so the build's own default still applies. + +## 2. `common/codenameone_settings.properties` (everything else) + +Hints with no annotation, and open-ended families such as `android.permission.`, are set as `codename1.arg.=` lines. This form still works exactly as it always has and nothing validates it — a misspelled key is accepted, never read, and silently does nothing. + +**Setting the same hint in both places fails the build.** Move a hint rather than copying it. + +## Annotated hints + +Every attribute below is generated from the build hint catalog, so it is always in step with what the builders actually read. + + + + +### `@IosPrivacy` + +| Attribute | Type | Build hint | +| --- | --- | --- | +| `calendarsFullAccessUsageDescription` | `String` | `codename1.arg.ios.NSCalendarsFullAccessUsageDescription` | +| `calendarsUsageDescription` | `String` | `codename1.arg.ios.NSCalendarsUsageDescription` | +| `calendarsWriteOnlyAccessUsageDescription` | `String` | `codename1.arg.ios.NSCalendarsWriteOnlyAccessUsageDescription` | +| `cameraUsageDescription` | `String` | `codename1.arg.ios.NSCameraUsageDescription` | +| `healthShareUsageDescription` | `String` | `codename1.arg.ios.NSHealthShareUsageDescription` | +| `healthUpdateUsageDescription` | `String` | `codename1.arg.ios.NSHealthUpdateUsageDescription` | +| `localNetworkUsageDescription` | `String` | `codename1.arg.ios.NSLocalNetworkUsageDescription` | +| `locationAlwaysAndWhenInUseUsageDescription` | `String` | `codename1.arg.ios.NSLocationAlwaysAndWhenInUseUsageDescription` | +| `locationAlwaysUsageDescription` | `String` | `codename1.arg.ios.NSLocationAlwaysUsageDescription` | +| `locationWhenInUseUsageDescription` | `String` | `codename1.arg.ios.NSLocationWhenInUseUsageDescription` | +| `microphoneUsageDescription` | `String` | `codename1.arg.ios.NSMicrophoneUsageDescription` | +| `remindersFullAccessUsageDescription` | `String` | `codename1.arg.ios.NSRemindersFullAccessUsageDescription` | +| `remindersUsageDescription` | `String` | `codename1.arg.ios.NSRemindersUsageDescription` | + +### `@Ios` + +| Attribute | Type | Build hint | +| --- | --- | --- | +| `addLibs` | `String[]` | `codename1.arg.ios.add_libs` | +| `applicationQueriesSchemes` | `String[]` | `codename1.arg.ios.applicationQueriesSchemes` | +| `beforeFinishLaunching` | `String` | `codename1.arg.ios.beforeFinishLaunching` | +| `bundleVersion` | `String` | `codename1.arg.ios.bundleVersion` | +| `dependencyManager` | `IosDependencyManager.AUTO\|COCOAPODS\|SPM\|BOTH\|NONE` | `codename1.arg.ios.dependencyManager` | +| `deploymentTarget` | `String` | `codename1.arg.ios.deployment_target` | +| `glAppDelegateHeader` | `String` | `codename1.arg.ios.glAppDelegateHeader` | +| `includePush` | `boolean` | `codename1.arg.ios.includePush` | +| `interfaceOrientation` | `String` | `codename1.arg.ios.interface_orientation` | +| `minDeploymentTarget` | `String` | `codename1.arg.ios.minDeploymentTarget` | +| `newStorageLocation` | `boolean` | `codename1.arg.ios.newStorageLocation` | +| `objC` | `boolean` | `codename1.arg.ios.objC` | +| `plistInject` | `String` | `codename1.arg.ios.plistInject` | +| `pods` | `String[]` | `codename1.arg.ios.pods` | +| `podsPlatform` | `String` | `codename1.arg.ios.pods.platform` | +| `podsSources` | `String[]` | `codename1.arg.ios.pods.sources` | +| `prerenderedIcon` | `boolean` | `codename1.arg.ios.prerendered_icon` | +| `projectType` | `IosProjectType.IOS\|IPAD\|IPHONE` | `codename1.arg.ios.project_type` | +| `spmPackages` | `String[]` | `codename1.arg.ios.spm.packages` | +| `teamId` | `String` | `codename1.arg.ios.teamId` | +| `themeMode` | `IosThemeMode.AUTO\|MODERN\|IOS7\|LEGACY` | `codename1.arg.ios.themeMode` | +| `uiscene` | `boolean` | `codename1.arg.ios.uiscene` | +| `urlScheme` | `String` | `codename1.arg.ios.urlScheme` | + +### `@Android` + +| Attribute | Type | Build hint | +| --- | --- | --- | +| `activityLaunchMode` | `String` | `codename1.arg.android.activity.launchMode` | +| `appBundle` | `boolean` | `codename1.arg.android.appBundle` | +| `buildToolsVersion` | `String` | `codename1.arg.android.buildToolsVersion` | +| `captureRecord` | `String` | `codename1.arg.android.captureRecord` | +| `debug` | `boolean` | `codename1.arg.android.debug` | +| `disableR8` | `boolean` | `codename1.arg.android.disableR8` | +| `enableProguard` | `boolean` | `codename1.arg.android.enableProguard` | +| `gradleDep` | `String[]` | `codename1.arg.android.gradleDep` | +| `hideStatusBar` | `boolean` | `codename1.arg.android.hideStatusBar` | +| `installLocation` | `InstallLocation.AUTO\|INTERNAL_ONLY\|PREFER_EXTERNAL` | `codename1.arg.android.installLocation` | +| `licenseKey` | `String` | `codename1.arg.android.licenseKey` | +| `minSdkVersion` | `int` | `codename1.arg.android.min_sdk_version` | +| `multidex` | `boolean` | `codename1.arg.android.multidex` | +| `newFirebaseMessaging` | `boolean` | `codename1.arg.android.newFirebaseMessaging` | +| `proguardKeep` | `String[]` | `codename1.arg.android.proguardKeep` | +| `release` | `boolean` | `codename1.arg.android.release` | +| `repositories` | `String[]` | `codename1.arg.android.repositories` | +| `targetSDKVersion` | `int` | `codename1.arg.android.targetSDKVersion` | +| `themeMode` | `AndroidThemeMode.AUTO\|MODERN\|HOLOLIGHT\|LEGACY` | `codename1.arg.and.themeMode` | +| `topDependency` | `String[]` | `codename1.arg.android.topDependency` | +| `useAndroidX` | `boolean` | `codename1.arg.android.useAndroidX` | +| `xapplication` | `String` | `codename1.arg.android.xapplication` | +| `xgradle` | `String[]` | `codename1.arg.android.xgradle` | +| `xpermissions` | `String` | `codename1.arg.android.xpermissions` | + +### `@Desktop` + +| Attribute | Type | Build hint | +| --- | --- | --- | +| `adaptToRetina` | `boolean` | `codename1.arg.desktop.adaptToRetina` | +| `fullscreen` | `boolean` | `codename1.arg.desktop.fullscreen` | +| `height` | `int` | `codename1.arg.desktop.height` | +| `interactiveScrollbars` | `boolean` | `codename1.arg.desktop.interactiveScrollbars` | +| `resizable` | `boolean` | `codename1.arg.desktop.resizable` | +| `titleBar` | `DesktopTitleBar.NATIVE\|CUSTOM\|TOOLBAR` | `codename1.arg.desktop.titleBar` | +| `width` | `int` | `codename1.arg.desktop.width` | + +### `@OnDeviceDebug` + +| Attribute | Type | Build hint | +| --- | --- | --- | +| `android` | `boolean` | `codename1.arg.android.onDeviceDebug` | +| `ios` | `boolean` | `codename1.arg.ios.onDeviceDebug` | +| `iosProxyHost` | `String` | `codename1.arg.ios.onDeviceDebug.proxyHost` | +| `iosProxyPort` | `int` | `codename1.arg.ios.onDeviceDebug.proxyPort` | +| `iosWaitForAttach` | `boolean` | `codename1.arg.ios.onDeviceDebug.waitForAttach` | + +### `@Build` + +| Attribute | Type | Build hint | +| --- | --- | --- | +| `facebookAppId` | `String` | `codename1.arg.facebook.appId` | +| `gcmSenderId` | `String` | `codename1.arg.gcm.sender_id` | +| `nativeTheme` | `NativeThemeMode.MODERN\|LEGACY\|CUSTOM` | `codename1.arg.nativeTheme` | +| `noExtraResources` | `boolean` | `codename1.arg.noExtraResources` | + +### `@Hardening` + +| Attribute | Type | Build hint | +| --- | --- | --- | +| `allowUnhardenedLocalBuild` | `boolean` | `codename1.arg.harden.allowUnhardenedLocalBuild` | +| `controlFlow` | `HardenControlFlow.OFF\|ON` | `codename1.arg.harden.controlFlow` | +| `keep` | `String` | `codename1.arg.harden.keep` | +| `level` | `HardenLevel.OFF\|STANDARD\|AGGRESSIVE\|PARANOID` | `codename1.arg.harden.level` | +| `rename` | `boolean` | `codename1.arg.harden.rename` | +| `strings` | `HardenStrings.OFF\|CONSTANTS\|ALL` | `codename1.arg.harden.strings` | + + + +## Hints with no annotation yet + +These are set in `common/codenameone_settings.properties`. ## Universal | Hint | Effect | | --- | --- | | `codename1.arg.java.version=17` | **Required.** Picks the JDK 17 build server toolchain. | -| `codename1.arg.build.compile=true` | Run the ahead-of-time / bytecode-to-native compile (recommended for iOS, smaller binaries). | -| `codename1.arg.build.timeout=180` | Build server timeout in minutes. Bump for very large apps. | | `codename1.arg.var.=...` | Define a custom variable referenced as `${var.name}` elsewhere in hints. | ## iOS | Hint | Effect | | --- | --- | -| `codename1.arg.ios.deployment_target=14.0` | Minimum iOS version. Set to the lowest iOS you actually support. | -| `codename1.arg.ios.teamId=ABCDEF1234` | Apple Developer Team ID; used by `ios-source` Xcode projects for code signing. | -| `codename1.arg.ios.includePush=true` | Include APNs entitlements + frameworks for push. | -| `codename1.arg.ios.add_libs=libsqlite3.0.dylib;libxml2.dylib` | Link extra system libraries. | -| `codename1.arg.ios.pods=Firebase/Core,Firebase/Analytics` | CocoaPods to include. | -| `codename1.arg.ios.pods.platform=14.0` | Pod platform target (must be >= deployment_target). | -| `codename1.arg.ios.pods.sources=https://github.com/CocoaPods/Specs.git` | Custom Pod source repos. | -| `codename1.arg.ios.objC=true` | Allow the iOS port to use Objective-C runtime features the strict mode would block. | -| `codename1.arg.ios.NSCameraUsageDescription=...` | Camera privacy description in `Info.plist`. See *iOS privacy strings* below for the pattern. | -| `codename1.arg.ios.NSLocationWhenInUseUsageDescription=...` | Location (in-use) privacy description. | | `codename1.arg.ios.NSPhotoLibraryUsageDescription=...` | Photo library privacy description. | -| `codename1.arg.ios.NSMicrophoneUsageDescription=...` | Microphone privacy description. | -| `codename1.arg.ios.plistInject=...raw XML...` | Inject raw `……` snippets into `Info.plist` for keys that don't have a dedicated `ios.NS*` hint above. | -| `codename1.arg.ios.glAppDelegateHeader=#import "MyHeader.h"` | Prepend custom imports to the generated AppDelegate. | | `codename1.arg.ios.statusbar_hidden=true` | Hide the iOS status bar. | -| `codename1.arg.ios.beforeFinishLaunching=...` | Native code inserted before iOS's `application:didFinishLaunchingWithOptions:` returns. | -| `codename1.arg.ios.newStorageLocation=true` | Use modern iOS storage paths (recommended for new apps). | | `codename1.arg.ios.wallet.extension=true` | Generate an Apple Wallet issuer-provisioning extension (iOS 14+). See *Apple Wallet issuer provisioning* below. | ## Android | Hint | Effect | | --- | --- | -| `codename1.arg.android.googlePlayVersion=true` | Build the Google Play–compatible APK/AAB variant. | -| `codename1.arg.android.sdkVersion=34` | Compile-time Android SDK. | -| `codename1.arg.android.targetSDKVersion=34` | Target SDK in the manifest (drives Play Store acceptance). | -| `codename1.arg.android.minSdkVersion=24` | Minimum Android API level. | -| `codename1.arg.android.buildToolsVersion=34.0.0` | Android build-tools version. | -| `codename1.arg.android.xPermissions=` | Inject extra `` lines into the manifest. | -| `codename1.arg.android.xapplication=` | Inject XML inside the manifest's `` element. | -| `codename1.arg.android.activity.launchMode=singleTask` | Launch mode for the main activity. | | `codename1.arg.android.statusbar_hidden=true` | Hide the Android status bar. | -| `codename1.arg.android.debug=false` | Whether to build a debug APK in addition to release. | -| `codename1.arg.android.licenseKey=...` | Google Play licensing key. | -| `codename1.arg.android.release=true` | Treat the build as a release (R8/ProGuard on, etc.). | -| `codename1.arg.android.proguardKeep=...` | Extra ProGuard `-keep` rules. | -| `codename1.arg.android.gradleDep=implementation 'com.example:lib:1.0'` | Inject Gradle dependencies. | ## Push notifications | Hint | Effect | | --- | --- | -| `gcm.sender_id=1234567890` | Firebase/GCM sender ID for Android push. | -| `codename1.arg.ios.includePush=true` | Pair with the FCM/APNs setup on the iOS side. | ## iOS privacy strings (`Info.plist`) @@ -112,8 +225,6 @@ This is an advanced, issuer-only feature — most apps never need it. The compil | `codename1.arg.javascript.proxy.allowedTargets=...` | Restrict the generated proxy to comma-separated origins, hosts, or wildcard subdomains. | | `codename1.arg.javascript.proxy.url=...` | Use an externally hosted proxy URL. This suppresses generated packaging unless `javascript.proxy.target` is also explicit. | | `codename1.arg.javascript.inject_proxy=false` | Disable proxy generation and proxy URL injection. | -| `codename1.arg.javascript.html5=true` | Emit modern ES output. | -| `codename1.arg.javascript.bundleResources=true` | Inline `theme.res` into the bundle (faster cold start). | ## Variable substitution diff --git a/scripts/initializr/common/src/main/resources/skill/references/mobile-adaptability.md b/scripts/initializr/common/src/main/resources/skill/references/mobile-adaptability.md index 39310e63e20..219c2f8abe4 100644 --- a/scripts/initializr/common/src/main/resources/skill/references/mobile-adaptability.md +++ b/scripts/initializr/common/src/main/resources/skill/references/mobile-adaptability.md @@ -222,6 +222,6 @@ The CN1 simulator has a "Skin" menu — pick "iPhone 15 Pro", "Pixel 8", "iPad", ## What CN1 explicitly does NOT do - Dark mode is opt-in: write a `@media (prefers-color-scheme: dark) { ... }` block in `theme.css` to recolor UIIDs (see `references/css.md`). For runtime overrides — toggling dark mode in-app regardless of system preference — call `Display.getInstance().setDarkMode(Boolean)`; read the current state with `Display.getInstance().isDarkMode()`. -- Orientation lock at runtime — call `Display.getInstance().lockOrientation(boolean portrait)` to pin the orientation while the app is running; `unlockOrientation()` releases it. Check `canForceOrientation()` first (some browsers / JavaScript runtimes don't allow it outside full-screen mode). The old `codename1.arg.ios.orientation` / `codename1.arg.android.screenOrientation` build hints are **discouraged** — `lockOrientation` works portably and dynamically across all platforms. +- Orientation lock at runtime — call `Display.getInstance().lockOrientation(boolean portrait)` to pin the orientation while the app is running; `unlockOrientation()` releases it. Check `canForceOrientation()` first (some browsers / JavaScript runtimes don't allow it outside full-screen mode). The `codename1.arg.ios.interface_orientation` build hint is **discouraged** (and Android has no equivalent hint) — `lockOrientation` works portably and dynamically across all platforms. - No automatic "iPad split view" support (the macOS-style split view) — design master/detail manually with `BorderLayout`. - No `vh` / `vw` units in CSS. Use percent insets in `LayeredLayoutConstraint`. diff --git a/scripts/initializr/common/src/main/resources/skill/references/native-interfaces.md b/scripts/initializr/common/src/main/resources/skill/references/native-interfaces.md index 37edc5cfceb..d06bbc2d55a 100644 --- a/scripts/initializr/common/src/main/resources/skill/references/native-interfaces.md +++ b/scripts/initializr/common/src/main/resources/skill/references/native-interfaces.md @@ -109,18 +109,21 @@ This step matters because every platform has a different stub layout, naming con The CN1 iOS port runs **without ARC** for these `.m` files (`CLANG_ENABLE_OBJC_ARC=NO`). Don't rely on autorelease-pool magic; retain manually or use static singletons for objects whose lifetime needs to outlive a method call. (This is also true for native code authored in `Ports/iOSPort/nativeSources/`.) -iOS Info.plist privacy strings have **dedicated build hint names** — set them directly, don't fall back to `ios.plistInject`. The pattern is `ios.=`: +iOS Info.plist privacy strings have **dedicated, compiler-checked names**. Set them with `@IosPrivacy` on the main class rather than hand-writing plist XML: -```properties -codename1.arg.ios.NSCameraUsageDescription=Scan QR codes to pair the device. -codename1.arg.ios.NSLocationWhenInUseUsageDescription=Find nearby branches near your location. -codename1.arg.ios.NSPhotoLibraryUsageDescription=Attach photos to support tickets. -codename1.arg.ios.NSMicrophoneUsageDescription=Record voice notes. +```java +@IosPrivacy( + cameraUsageDescription = "Scan QR codes to pair the device.", + locationWhenInUseUsageDescription = "Find nearby branches near your location.", + microphoneUsageDescription = "Record voice notes." +) +public class MyAppName extends Lifecycle { +} ``` -App Store builds reject location, camera, microphone, photo, contacts, etc. without the appropriate descriptions. Use `ios.plistInject` only for raw XML keys that don't have a dedicated hint. +App Store builds reject location, camera, microphone, photo, contacts, etc. without the appropriate descriptions. Use `@Ios(plistInject = "...")` only for raw XML keys that have no dedicated attribute. -If you need a CocoaPod dependency, add `codename1.arg.ios.pods=PodName,...` to `codenameone_settings.properties`. +If you need a CocoaPod dependency, add it with `@Ios(pods = {"PodName"})`. ### Android (Java) @@ -147,13 +150,15 @@ public class GpsBridgeImpl { } ``` -Permissions in the Android manifest are injected via `codename1.arg.android.xPermissions`. For example: +Permissions in the Android manifest are injected with `@Android(xpermissions = ...)`: -```properties -codename1.arg.android.xPermissions= +```java +@Android(xpermissions = "") +public class MyAppName extends Lifecycle { +} ``` -Extra Gradle dependencies go in `codename1.arg.android.gradleDep`. See `references/build-hints.md`. +Extra Gradle dependencies go in `@Android(gradleDep = {"implementation 'com.example:lib:1.0'"})`. See `references/build-hints.md`. ### JavaScript (TeaVM-friendly JS) @@ -299,6 +304,6 @@ navigator.geolocation.watchPosition(function(pos) { - **Method signature mismatch between the interface and the stub** — happens after you edit the Java interface but forget to regenerate. Re-run `mvn cn1:generate-native-interfaces -Dcn1.generateNativeInterfaces.overwrite=true` and re-apply your platform code. - **Returning Java objects** — not supported by the bridge marshaler. Return primitives, `String`, `byte[]`, or `PeerComponent` only. - **`PeerComponent` on iOS without ARC** — peer-component implementations can dangle if you treat the bridge like an ARC-managed Swift method. Retain natively, or wrap returned views in a static holder. -- **Permissions / Info.plist** — the build server happily accepts a native interface that calls a privacy-protected API, but the App Store / Play Store reject it. Set `codename1.arg.ios.plistInject` and `codename1.arg.android.xPermissions` (see `references/build-hints.md`). +- **Permissions / Info.plist** — the build server happily accepts a native interface that calls a privacy-protected API, but the App Store / Play Store reject it. Set `@IosPrivacy(...)` for the plist strings and `@Android(xpermissions = ...)` for the manifest (see `references/build-hints.md`). - **Forgetting `isSupported()` return** — defaults to `false`, so the Java side thinks the bridge isn't available. Always override. - **`NativeLookup.create()` returns null in the simulator only** — usually means the `javase/` impl class is missing or in the wrong package. diff --git a/scripts/initializr/common/src/main/resources/tweet-src.zip b/scripts/initializr/common/src/main/resources/tweet-src.zip index add354048e9050391925ac291ca7400f911061c2..431c10e5a9a8da29900812fcc29903d5d2366bcc 100644 GIT binary patch delta 4024 zcmZ`+2{=@38=l3eX~tkA+gOU37P}-{NTraHsVP$SeK!gzgOt9~hbB%%^k)mzr<5go z_L8!bElIMbP)s!cIkWWP`u}&Xxvq2G`+l}}dFGzFG2!Vx;W&M9!*wti%-@OXbH?An ziK=XFisV@j&a8z6UQ(v0Mqh|>0SSs*VXzG=c#ck9KF&@~j!HpZo&}$+P;Tqu5aMfK zFn7DNcFOc-32{C&$Y;Gd_;@MDiVF)ae|HM9^YZm{0_Tw;Fc@71EehEnH?p6B56-A{ z^k6sv&Vtylg>d1#QMkq$)|?#O7R^TG08LkvL|zv<7QsQTV+naRSUn!j>lQ)DJUhVx zq>zmLhEvILrzUE^G*3vuU_?%^VmB0y)^0iO)1!%JCYMJfA~*Pdc=e?p5z^&(t^P4R zs57R5^1k>mTv1hH=lU$!t;I%h%q8b7S_z-_mztfcA2W4ym(p*-j#Q?ppS!o+XjAzVveu5a5#DYe zR7K8&Mh=AB3S)ROH|P6$znY}he>RY(eKBz|C^<|x9;Kch(J#%IGW2bXeicyt!!pby zOGPGL{kQtireta`?8vT?2z6my|HZ@uInxx}-zo0TVMyeNz{G`y6X(ef3ATuz%9@^) z{6Ms&dADGRcjvbKQ*S)tb0st@_HTS`si!Kqbmnn#Quf<3$@GryZnT!{V3I_{6Pjs4 zTdWxUAo;bu+NrpKEw??+GN%H(z1%~+o+rE>rau`h87lI*TlRImyrW#Vk0K+vSKe$Q zDNemLOD+1I_?g2=%)%r=G|p1x#)GZd=@QanH^k)T?C?~j)?4k zR1gsksCjA0e>ifjg|8xk@^Ed6ak}LM-9sH-8EKZbDY11o1-pKeMXcUt}P+^Hb83hbc7MY@UzyTNNmab^<^2&L)OQKb60(5`CfdOfxQ?;;FdHan#qtR z&^c23vFK;l%d%i*x?v>0f&*oT<;#-Vg^m#u;>;Us#lf1MP4dPbQ%h_84D)C17qp)L z-RRUa$zK>_*zrBNu8^&uN93e z&yU+b3rj-AYyV89B%&zQAM)uP z4J?=(+aq@=+c6X)X^_X;nlh^w&{HXzcB!=4x24)Z#;2dI9OFbKl&-;AQ733PMyc_< ziEq@l;pXNFooW9a;>?lwFdzB3So0-c_1`~SXX|7{nX17=2~h)LY+apMNE=PjuQi;~ zrUuBkt)R?|+PPExk?{|{@dLj-2b!orEaHJn+D?RpD8fl0B1}e5N zb~R5b_#+OPC!A}qYzj0xT@^!1iV>7BkjP^?H=cN~NU{mrNwh0@6FH~*1}4;&SsQw6 zemdkMTzFwnGVZp(b!6K7Yl`BvJ^r! zt?a_DMWiV2Am&z4#p{4l*=*W}rG=5N5rG%y-S9h3pSe{s7E{ruDSSBJrFKryh`L=z zzxmi9^st;AmA=hekMPwz8EI>(!g2C@2vv|o)UELe_;PKJY%bQ*?X(iN}JjNqy zQsu@a>!2ocMx^AvvM*HR(#z9Lp?9w2t)i_Ro6YkZlEy@p zmHL|0ssirtr#m*O@9`i$RPwn~gfVoz5t&zG;^dg6R#KOK&HA0yfqvr}N0aNt`H{D+ zj_p1gd7L@&@x#Lb4B2amoY7A^b~EUFl|p~}ZUYI`}Qdh}a9%?^^nC_<96^*(D&gI2KqN{KR z7OhfC$gXqw4?oT0{gS1}Pw)Nbu80y%cL6wJg_1zZaO8z80Zo@Da1;gImO#k6MJVCr z1+|ZzBPc^~EExnoo^^8yq_Px@G7eHaf2JTAvr-*lW8|v3Kn{;63Wlkzz87!n3Sb<9)RZ1Eq~j4bdCj}S+yg08~rWp6a_ z7uX0P)~5pco^U*ekc8yHAV9^H>h{_sJlqxVNOT+?$ zZYY8Tq-og$0zY#>=xDI4Wg(IKFM$uUOagNyFGQ5$Ury7-uw^b3LJ*X|oB@UK<3Nxg z<~28kilkqFi*n4_73D7D&_R{VN>xyn>jnn-krIMJ$N?iRe`2$ZZ8!iVq5%)rRjBd? zmKhzC)WGy=@Ub`>1O>JtJ2m$D{|}wb$^{BI8D1pCE*4VVP^K%FqLRcy!TX8kma9xy zSuXPrg}|zG1J8;|rxn?kmbD**m1hR8wERM|tYx4}&K}S@X|G_g_VuyHvK*lkZ|~Q(7&R8&8f=JVHV-0P9t(thp~1clLbox4W55ovKM8L4bZ{0bo&lK)D}EinGb=jC1~Bq3q5DX!x&! z)1R=7Ic*HcUQMXUg9ysdE=W^X8MmASDyb+U;7dhucM|YEff8MjK!+_vQUfpntE{u^ eAV3a)8s7$UQxy2?1cQ;l&rvK4cG(_kP5%Wz$mbvc delta 5747 zcma)A2{@E%6#i%ViLobJV`7k^ER8#KE2-P!B3Y)SlqNGW)~p#zQ;H&W)2QJVT}unf za*0+Vp>A1IRF))_BBZqH{{Q?lGVaWDd3bo9^PcxT=R4my=bNF98MXa0*s?ecJrKYH z-qbLv@j8kWfEoHbi2?tFhT{Mf_B{#!u*v`cumf=#bEWu}9sz!cHBqtJLzuNJ4o~8F zg>C8KRKFd*bg>K$wiqm@$OBYE;W^rLP!0bRIe4Dk>>WV?VGJ5QC|JCtLL48#evX^< z!@I}3{{&l%l_5(a?sXAEQE|FY=Q&*}-r?2hN6>Vn2@y3ZNmRP>=TMbR|#xgU@ zFw%0D#>y0YDExa>&{33Cgi15-B9qR@aW;9NWdq;9uI`m5S-FNyP9j%wS*eZOvaLjJMZ;YC4d6l2ro!Tz(~8V3!u-xFS` z9ne2RUfjf}t4ufYQrnVjfB8J`*2$C5{-RV~`&)OFbGS(pp9<3Mm^{b+BG zmTmQ$RSzv6OV=AcD{#Onc+s!M7;HW}l9|%{W+2|mwsN60-JINYPkm%oxAYL_Z=ZC} z0~!_bM~IL1+@Yn%G>Q_emSGa9$3BHvqkj9O!GbtIx3!!7 zG$!gV8j%{}n(n2U+m+Y)DXQF&EKw-c>-{OW=ud5XU{>yELgGH%2()e@ZH}@+@gcP& zYW1at7*nZ6Es~bAsoCS^3x|~BleIsx>(3o>YjskSy?l9##kzzLm2*$>+ojUYu;s+q z4|)x!l~|QUJ)1imbW|MdOI6XALw~)uXHy>gpZn)E_hK3A-fXCeFc~#?tx@K+#_^A^ zvwh^q3mYT1?(4PAd89?9Cv%cqpPM;%!?A;D&+V!odlUOUQU{Kl z&Q5!~S!Sz!SjRmB%BdxX)53RFp3HJ;Z`YBGPIX>=-hmZd?%~_q{~)cxo@_HuPk!%b zkHR}kIp6gk7#wIwD~Mrh?*N zhAk>*ef(|8Zw4-&E;LJO=f1n@FKE*)wQ^`4Dqf22M(w?&GuHKzQ!(4pHPB^u^6+l; z7Y2iKH)cI$J=xi@EUVS0c$f3eM+LV6G?WT0;*G8QnMCQ3PZU~yu=x&_rFrB-zZcX-M%df6w>G?s zZjP$DVRp=J;9`cI&OmXXRUz$r(o1PJzIIx|a>Gr=j{}ojimtcSNX%URx^k)FoI|PZ zdecAZp?xvL{Q0)%ZB<_>?G?w=eOJuOCI%S&zFXG!Igq37XIffmqMZF{bi-JFU}=EO zT$*HZ=9#;f&ZMwhqhfLr4hEiodNWh^rM1Kt#&JoX*s6T3(hYhw>uc*P&Uwb`sorIs z>Ka=%ljE{a!g9T|@2cy!Zl|{fT=CC~Y+>c#dR4-$HD3B@xyzS+lls#4;6hi~Ys`yI zzp^X(E}EgWp=tGhbzBQ$slD8l^;3yE{Gl)CKj8&zT6Yq3Ke;?o9-9hXO z$-Hxi%r^IvyythNXWYNx(ym(;T_5Ua{&~^z`0CN1zW3}qloRV4YiBfOM_Rl~FClEN zPF|Kwb6%X0qPf2P6l+dPt>c=M&Jbou9Fr}#uscDyDLf{JG{0pu+DztlqT|Tdq~h+R zuO+#98iB)wx^qYR`xfo5vK@D;xlOuy+@9@qB#gM2YCS(SftXs7S`|T+*=1O0aO{0c z%PReKJ;c7&IJ?xKt@xcqhtWU1~1)>O4QADnj}ap=wC5Si`Yt~<5XKMO6-wH|JhE@9@~ ztg^zOuby6JrT=O9oZ7|_$F;uIjTi6CYSs1p^uDaXgpU>-<;Df{4{*yvtf@;AoS@&|9m+`%cCLJRfhM z<|ifwq_Qeg#?pe7R@3ZCYI4Y=tLut}ADeGNhjfnXmgf`%c2%=}_s>4(_>d7aUuVua z!aaf{?rT(aFPKvFqB3Yxi%M&;E!wRT74L4CjEnVj|HmnAt)jl{m`7(qjkl^H+t~Iy znq4`YKZo^#=|N!(5Bg6A_xA|^+f0Ab=-eh`a69N}h z=sS55#4JCyasuW*+koJ02Hu;d0Xt)j*US8&d$SGt532?Ms?cm!@Z#?`q85u2Mx)RQ z5GaFHT{tnmg)CYyjWpyK0RBvIbmRWP`-O*SAUJP(C^?nPsE2;0Zgo$M;lqIKjx#`6 z@w?6(lj0w?I6^RuD-8DB_g~M&5~fZWh`A2p_M&hJ9266!fiZ>DK4pLl5K|F8%Q9rJ z%2}MQP?Qql*@)ohD=s@_#4ywsc<+J&)ZyIl2Ic;be;gB~fH6bTr^6xmfJ*-dRZ)TF zsnX%>_Te+ZK?}(aFA`M`%mk*>2b2-d{mj$eEo5 zSvL9dk3d9SmVGY3*7AJna3IanKNB%rgdLgyK&p8~CQ6A?3HHfEkWe0Fe&%1x4Qz(D zW&ROQ07OK<(WQd?!h{c3flnaH{tFd6#16)(A^n0L91t4xvzC=K2X6-TmI+%L-7mnC zPNx}#^XgRuSCJb-niIGk)G!7Cs8evi6o7$c@E^Pv8i>5mrrcxBkOzn-NeO_K@CF}gX(JQC?YVBT7ul<00}5Af;jmp zCqnR2+5{GQn*!N;m9Mkx;mZxf=^b$BYS!xe+@!5f8WzW%8=6dH@*;MGE0ZXl(2MZuK1 zK_A^gDK#N*6Ds6Xkz(K!6kz$)fShc@8BU`wNJ36kNbya+VsH~4|ByIvAA%mm0DzG| znxCKJ$%mH`aq`{$rX*TB??>RgYak>7&b6sH8)pzn7`W7P1U!sxw$hlEzr38awd zIpI^0uC6>Jyt(i>g(2a-Z6?jj5Yir;HiDCO67ER}LzZs?36#mDe_Q}3xXTD{#}2k2 U^g$#5%!a;u cn1-settings-common jar + + + true + cn1-settings-common + + com.codenameone + codenameone-build-hint-catalog + com.codenameone codenameone-core @@ -74,13 +82,6 @@ ${project.basedir}/src/main/resources - - ${project.basedir}/../../../docs/developer-guide - - Advanced-Topics-Under-The-Hood.asciidoc - - com/codename1/settings/hints - @@ -131,7 +132,10 @@ org.apache.maven.plugins maven-surefire-plugin - true + + ${cn1.settings.skipTests} diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java index 6c230eeca6d..9b2c3666391 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java @@ -80,7 +80,12 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import com.codename1.annotations.buildhints.*; +@Android(themeMode = AndroidThemeMode.MODERN) +@Build(nativeTheme = NativeThemeMode.MODERN) +@Desktop(height = 820, interactiveScrollbars = true, titleBar = DesktopTitleBar.NATIVE, width = 1260) +@Ios(themeMode = IosThemeMode.MODERN) public class CodenameOneSettings extends Lifecycle { public enum Section { BASIC, BUILD_HINTS, EXTENSIONS, ADVANCED } @@ -90,7 +95,7 @@ public enum Section { BASIC, BUILD_HINTS, EXTENSIONS, ADVANCED } private ProjectBinding binding; private SettingsProperties settings; - private BuildHintCatalog buildHints = BuildHintCatalog.fallback(); + private BuildHintCatalog buildHints = BuildHintCatalog.load(); private Section section = Section.BASIC; private Form form; private Container page; @@ -221,38 +226,7 @@ private void loadProject() { } catch (Exception ex) { Log.e(ex); } - buildHints = loadBuildHints(binding.buildHintsDoc()); - } - } - - private BuildHintCatalog loadBuildHints(String docPath) { - InputStream in = null; - if (docPath != null && docPath.length() > 0) { - try { - String url = ProjectIO.fsUrl(docPath); - FileSystemStorage fs = FileSystemStorage.getInstance(); - if (fs.exists(url)) { - in = fs.openInputStream(url); - return BuildHintCatalog.fromAsciiDoc(Util.readToString(in, "UTF-8")); - } - } catch (Exception ex) { - Log.e(ex); - } finally { - Util.cleanup(in); - in = null; - } - } - try { - in = getClass().getResourceAsStream("/com/codename1/settings/hints/Advanced-Topics-Under-The-Hood.asciidoc"); - if (in == null) { - return BuildHintCatalog.fallback(); - } - return BuildHintCatalog.fromAsciiDoc(Util.readToString(in, "UTF-8")); - } catch (Exception ex) { - Log.e(ex); - return BuildHintCatalog.fallback(); - } finally { - Util.cleanup(in); + buildHints = BuildHintCatalog.load(); } } @@ -817,6 +791,20 @@ private boolean isValidHintValue(BuildHintMetadata meta, String value) { return true; } String v = value.trim(); + // A closed value domain is the one case where a wrong value is certain to + // be wrong: the builder compares against these strings and silently uses + // its default when it recognises none of them. + if (!meta.values().isEmpty()) { + for (String allowed : meta.values()) { + if (allowed.equalsIgnoreCase(v)) { + return true; + } + } + return false; + } + if (meta.type() == BuildHintType.BOOLEAN) { + return "true".equalsIgnoreCase(v) || "false".equalsIgnoreCase(v); + } if (meta.type() == BuildHintType.INTEGER) { return isDigits(v); } @@ -1544,9 +1532,6 @@ private void renderAdvanced() { Container c = card("Files"); actionRow(c, "Settings file", binding.settings(), () -> Display.getInstance().execute(ProjectIO.fsUrl(binding.settings()))); actionRow(c, "Common POM", binding.pom(), () -> Display.getInstance().execute(ProjectIO.fsUrl(binding.pom()))); - if (binding.buildHintsDoc() != null && binding.buildHintsDoc().length() > 0) { - actionRow(c, "Build-hints source", binding.buildHintsDoc(), () -> Display.getInstance().execute(ProjectIO.fsUrl(binding.buildHintsDoc()))); - } page.add(c); } diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintCatalog.java b/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintCatalog.java index e75d0bc3b5b..f6191f5d820 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintCatalog.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintCatalog.java @@ -1,5 +1,8 @@ package com.codename1.settings.hints; +import com.codename1.build.shared.BuildHints; +import com.codename1.build.shared.HintType; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -7,6 +10,15 @@ import java.util.List; import java.util.Map; +/** + * The build hints the Settings tool offers for editing. + * + *

Built from {@link BuildHints}, the same table the {@code @Ios} / {@code @Android} + * annotations are generated from and the same one the builders' drift gate checks. It + * used to be scraped out of the developer guide's AsciiDoc table at runtime, with the + * type guessed by string-matching the description prose -- so a hint the guide did not + * mention was invisible here, and one whose wording changed silently changed type.

+ */ public final class BuildHintCatalog { private final Map hints = new LinkedHashMap(); @@ -38,181 +50,46 @@ public void add(BuildHintMetadata hint) { } } - public static BuildHintCatalog fromAsciiDoc(String asciidoc) { + /** + * Every hint the catalog describes, including the ones consumed only by the + * build service. Dynamic families such as {@code android.permission.} + * are left out: their names are patterns rather than keys, so there is + * nothing for the editor to set. + */ + public static BuildHintCatalog load() { BuildHintCatalog catalog = new BuildHintCatalog(); - if (asciidoc == null) { - return fallback(); - } - String[] lines = asciidoc.replace("\r\n", "\n").split("\n"); - boolean inTable = false; - boolean buildHintTable = false; - String currentName = null; - StringBuilder currentDescription = new StringBuilder(); - for (String raw : lines) { - String line = raw.trim(); - if ("|===".equals(line)) { - if (inTable) { - if (buildHintTable) { - flush(catalog, currentName, currentDescription.toString()); - break; - } - inTable = false; - } else { - inTable = true; - buildHintTable = false; - currentName = null; - currentDescription.setLength(0); - } - continue; - } - if (!inTable) { - continue; - } - if (line.startsWith("//")) { - continue; - } - if (!buildHintTable) { - String header = line.startsWith("|") ? line.substring(1).trim() : line; - if (header.startsWith("Name") && header.contains("|Description")) { - buildHintTable = true; - } + for (BuildHints.Hint h : BuildHints.entries()) { + if (h.isDynamic()) { continue; } - if (line.startsWith("|")) { - String cell = line.substring(1).trim(); - if (currentName == null) { - currentName = cell; - currentDescription.setLength(0); - } else if (currentDescription.length() == 0) { - currentDescription.append(cell); - } else { - flush(catalog, currentName, currentDescription.toString()); - currentName = cell; - currentDescription.setLength(0); - } - } else if (currentName != null && line.length() > 0) { - if (currentDescription.length() > 0) { - currentDescription.append(' '); - } - currentDescription.append(line); - } - } - if (catalog.hints.isEmpty()) { - return fallback(); + catalog.add(new BuildHintMetadata( + h.name(), + h.doc(), + toSettingsType(h.type()), + h.platform(), + h.values(), + h.def(), + annotationOf(h))); } return catalog; } - private static void flush(BuildHintCatalog catalog, String rawName, String description) { - if (rawName == null || rawName.trim().length() == 0) { - return; - } - for (String name : splitNames(rawName)) { - catalog.add(new BuildHintMetadata(name, description, inferType(name, description), inferPlatform(name))); - } - } - - private static List splitNames(String raw) { - ArrayList names = new ArrayList(); - String normalized = raw.replace("`", "").replace("(a.k.a.", "/").replace(")", ""); - String[] parts = normalized.split(","); - for (String part : parts) { - String[] slashParts = part.split("/"); - for (String slashPart : slashParts) { - String name = slashPart.trim(); - if (name.indexOf(' ') >= 0 || name.length() == 0 || name.startsWith("(")) { - continue; - } - names.add(name); - } - } - return names.isEmpty() ? Collections.singletonList(raw.trim()) : names; - } - - private static BuildHintType inferType(String name, String description) { - String n = name.toLowerCase(); - String d = description == null ? "" : description.toLowerCase(); - if ("java.version".equals(name)) { - return BuildHintType.INTEGER; - } - if ("android.targetSDKVersion".equals(name)) { - return BuildHintType.INTEGER; - } - if ("android.useAndroidX".equals(name)) { - return BuildHintType.BOOLEAN; + private static String annotationOf(BuildHints.Hint h) { + if (!h.isAnnotated()) { + return null; } - if ("build.cn1Version".equals(name) || "ios.bundleVersion".equals(name)) { - return BuildHintType.VERSION; - } - if (n.contains("password") || n.contains("secret") || n.contains("token")) { - return BuildHintType.SECRET; - } - if (n.contains("certificate") || n.contains("provision") || n.contains("sdkroot") || d.contains("path to")) { - return BuildHintType.PATH; - } - if (n.contains("url") || d.contains("https://") || d.contains("http://")) { - return BuildHintType.URL; - } - if (d.contains("true/false") || d.contains("boolean true/false") || d.contains("`true`") || d.contains("`false`")) { - return BuildHintType.BOOLEAN; - } - if (d.contains("comma") || d.contains("comma-delimited") || d.contains("comma delimited")) { - return BuildHintType.CSV; - } - if (d.contains("<") && d.contains(">") || n.contains("xml") || n.contains("plistinject") || n.contains("xpermissions")) { - return BuildHintType.XML; - } - if (n.contains("version") || d.contains("version")) { - return BuildHintType.VERSION; - } - if (d.contains("can be ") || d.contains("supported values") || d.contains("accepts ")) { - return BuildHintType.ENUM; - } - if (d.contains("integer") || d.contains("size in bytes") || n.endsWith("port")) { - return BuildHintType.INTEGER; - } - return BuildHintType.TEXT; + return "@" + h.group().annotationSimpleName() + "(" + h.attr() + ")"; } - private static String inferPlatform(String name) { - if (name.startsWith("android.") || name.startsWith("and.")) { - return "android"; + /** + * Maps the catalog's type to this tool's vocabulary. Derived rather than + * duplicated so the two cannot drift apart again. + */ + private static BuildHintType toSettingsType(HintType type) { + try { + return BuildHintType.valueOf(BuildHints.settingsType(type)); + } catch (IllegalArgumentException ex) { + return BuildHintType.TEXT; } - if (name.startsWith("ios.")) { - return "ios"; - } - if (name.startsWith("macNative.") || name.startsWith("codename1.mac.") || name.startsWith("desktop.mac.")) { - return "mac"; - } - if (name.startsWith("windows.") || name.startsWith("win.")) { - return "windows"; - } - if (name.startsWith("linux.")) { - return "linux"; - } - if (name.startsWith("javascript.")) { - return "javascript"; - } - if (name.startsWith("desktop.")) { - return "desktop"; - } - return "general"; - } - - public static BuildHintCatalog fallback() { - BuildHintCatalog catalog = new BuildHintCatalog(); - catalog.add(new BuildHintMetadata("build.cn1Version", "Pins the cloud build to a released Codename One version such as 7.0.250, or master.", BuildHintType.VERSION, "general")); - catalog.add(new BuildHintMetadata("java.version", "Build server Java version.", BuildHintType.INTEGER, "general")); - catalog.add(new BuildHintMetadata("android.debug", "Whether to include an Android debug build.", BuildHintType.BOOLEAN, "android")); - catalog.add(new BuildHintMetadata("android.release", "Whether to include an Android release build.", BuildHintType.BOOLEAN, "android")); - catalog.add(new BuildHintMetadata("android.xpermissions", "Additional Android manifest permissions XML.", BuildHintType.XML, "android")); - catalog.add(new BuildHintMetadata("ios.bundleVersion", "Version number of the generated iOS bundle.", BuildHintType.VERSION, "ios")); - catalog.add(new BuildHintMetadata("ios.deployment_target", "Minimum iOS version.", BuildHintType.VERSION, "ios")); - catalog.add(new BuildHintMetadata("ios.plistInject", "Raw XML injected into the iOS Info.plist.", BuildHintType.XML, "ios")); - catalog.add(new BuildHintMetadata("macNative.distribution", "Mac native distribution: appStore, developerID, or both.", BuildHintType.ENUM, "mac")); - catalog.add(new BuildHintMetadata("windows.signing.timestampUrl", "RFC 3161 timestamp server URL for Windows signing.", BuildHintType.URL, "windows")); - catalog.add(new BuildHintMetadata("desktop.width", "Desktop window width.", BuildHintType.INTEGER, "desktop")); - catalog.add(new BuildHintMetadata("desktop.height", "Desktop window height.", BuildHintType.INTEGER, "desktop")); - return catalog; } } diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintMetadata.java b/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintMetadata.java index e5e27a1d789..dcb1cfdc2bc 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintMetadata.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintMetadata.java @@ -1,16 +1,56 @@ package com.codename1.settings.hints; +import java.util.Collections; +import java.util.List; + public final class BuildHintMetadata { private final String name; private final String description; private final BuildHintType type; private final String platform; + private final List values; + private final String defaultValue; + private final String annotation; public BuildHintMetadata(String name, String description, BuildHintType type, String platform) { + this(name, description, type, platform, null, null, null); + } + + /** + * @param values the closed value domain, or null when the hint is free-form + * @param defaultValue the builder's own default, or null when it has none + * @param annotation the annotation attribute that sets this hint, e.g. + * {@code @Ios(pods)}, or null when it has none + */ + public BuildHintMetadata(String name, String description, BuildHintType type, String platform, + List values, String defaultValue, String annotation) { this.name = name; this.description = description == null ? "" : description.trim(); this.type = type == null ? BuildHintType.TEXT : type; this.platform = platform == null ? "general" : platform; + this.values = values == null || values.isEmpty() + ? Collections.emptyList() : Collections.unmodifiableList(values); + this.defaultValue = defaultValue; + this.annotation = annotation; + } + + /** The accepted values, or empty when the hint is free-form. */ + public List values() { + return values; + } + + /** The builder's own default, or null. */ + public String defaultValue() { + return defaultValue; + } + + /** + * The annotation attribute that sets this hint, or null when the hint has no + * checked form yet. Editing such a hint here is not wrong, but the annotation + * is the form the compiler validates. + */ + public String annotation() { + return annotation; } public String name() { diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/project/ProjectBinding.java b/scripts/settings/common/src/main/java/com/codename1/settings/project/ProjectBinding.java index ff66d7e231d..1f72dafe25f 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/project/ProjectBinding.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/project/ProjectBinding.java @@ -5,7 +5,6 @@ public final class ProjectBinding { private String settings; private String pom; private String multimoduleRoot; - private String buildHintsDoc; public String projectDir() { return projectDir; @@ -23,10 +22,6 @@ public String multimoduleRoot() { return multimoduleRoot; } - public String buildHintsDoc() { - return buildHintsDoc; - } - public boolean isValid() { return settings != null && settings.length() > 0; } @@ -53,7 +48,6 @@ public static ProjectBinding parse(String content) { case "settings" -> b.settings = val; case "pom" -> b.pom = val; case "multimoduleRoot" -> b.multimoduleRoot = val; - case "buildHintsDoc" -> b.buildHintsDoc = val; default -> { } } diff --git a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java index dbd47edf61f..23a7e8f2a39 100644 --- a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java +++ b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java @@ -1,54 +1,91 @@ package com.codename1.settings; import com.codename1.settings.hints.BuildHintCatalog; +import com.codename1.settings.hints.BuildHintMetadata; import com.codename1.settings.hints.BuildHintType; import org.junit.jupiter.api.Test; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * The hint catalog the Settings tool offers for editing. + * + *

It used to be scraped out of the developer guide's AsciiDoc table at runtime, + * with each hint's type guessed by string-matching its description prose. It now + * comes from {@code com.codename1.build.shared.BuildHints}, the same table the + * build hint annotations are generated from and the same one the drift gate holds + * the builders against.

+ */ public class BuildHintCatalogTest { - @Test - public void parsesDeveloperGuideBuildHintTable() { - String doc = """ - Before - |=== - |Name\t|Description - - |android.debug - |true/false defaults to true - indicates whether to include debug. - - |ios.plistInject - |Injects raw XML into the plist. - - |windows.signing.timestampUrl - |RFC 3161 timestamp server URL. - |=== - After - """; - BuildHintCatalog catalog = BuildHintCatalog.fromAsciiDoc(doc); + @Test + public void carriesTheHintsTheDeveloperGuideDocuments() { + BuildHintCatalog catalog = BuildHintCatalog.load(); assertNotNull(catalog.get("android.debug")); + assertNotNull(catalog.get("ios.plistInject")); + assertNotNull(catalog.get("windows.signing.timestampUrl")); + assertTrue(catalog.all().size() > 400, + "expected the full catalog, got " + catalog.all().size()); + } + + @Test + public void knownHintsCarryTheRightType() { + BuildHintCatalog catalog = BuildHintCatalog.load(); assertEquals(BuildHintType.BOOLEAN, catalog.get("android.debug").type()); assertEquals(BuildHintType.XML, catalog.get("ios.plistInject").type()); - assertEquals(BuildHintType.URL, catalog.get("windows.signing.timestampUrl").type()); + assertEquals(BuildHintType.INTEGER, catalog.get("java.version").type()); + assertEquals(BuildHintType.INTEGER, catalog.get("android.min_sdk_version").type()); + assertEquals(BuildHintType.BOOLEAN, catalog.get("android.useAndroidX").type()); + assertEquals(BuildHintType.CSV, catalog.get("ios.pods").type()); } + /** + * The tool used to accept any string for every hint but an integer, a version + * or a URL. A hint with a closed domain is the one case where a wrong value is + * certainly wrong, because the builder compares against those strings and + * silently falls back to its default when it matches none of them. + */ @Test - public void packagedDeveloperGuideCatalogProvidesKnownHintTypes() throws Exception { - try (InputStream in = CodenameOneSettings.class.getResourceAsStream( - "/com/codename1/settings/hints/Advanced-Topics-Under-The-Hood.asciidoc")) { - assertNotNull(in, "The Settings jar should carry the developer-guide build hint table."); - String doc = new String(in.readAllBytes(), StandardCharsets.UTF_8); - BuildHintCatalog catalog = BuildHintCatalog.fromAsciiDoc(doc); - assertEquals(BuildHintType.INTEGER, catalog.get("java.version").type()); - assertEquals(BuildHintType.VERSION, catalog.get("build.cn1Version").type()); - assertEquals(BuildHintType.VERSION, catalog.get("ios.bundleVersion").type()); - assertEquals(BuildHintType.INTEGER, catalog.get("android.targetSDKVersion").type()); - assertEquals(BuildHintType.BOOLEAN, catalog.get("android.useAndroidX").type()); + public void hintsWithAClosedDomainExposeIt() { + BuildHintMetadata titleBar = BuildHintCatalog.load().get("desktop.titleBar"); + assertNotNull(titleBar); + assertEquals(BuildHintType.ENUM, titleBar.type()); + assertTrue(titleBar.values().contains("native")); + assertTrue(titleBar.values().contains("custom")); + assertTrue(titleBar.values().contains("toolbar")); + assertFalse(titleBar.values().contains("natvie")); + } + + /** A hint with a checked form should say so, so the UI can point at it. */ + @Test + public void annotatedHintsNameTheirAnnotation() { + BuildHintCatalog catalog = BuildHintCatalog.load(); + assertEquals("@Ios(pods)", catalog.get("ios.pods").annotation()); + assertEquals("@Desktop(titleBar)", catalog.get("desktop.titleBar").annotation()); + // Not every hint has one; the properties file remains the way to set those. + assertEquals(null, catalog.get("android.xmanifest").annotation()); + } + + /** + * Dynamic families such as {@code android.permission.} are patterns, not + * keys, so there is nothing for the editor to set. + */ + @Test + public void dynamicFamiliesAreNotOffered() { + BuildHintCatalog catalog = BuildHintCatalog.load(); + for (BuildHintMetadata h : catalog.all()) { + assertFalse(h.name().contains("*"), + h.name() + " is a pattern, not a hint the editor can set"); } } + + @Test + public void searchStillMatchesOnNameAndDescription() { + BuildHintCatalog catalog = BuildHintCatalog.load(); + assertFalse(catalog.search("pods").isEmpty()); + assertFalse(catalog.search("android").isEmpty()); + } } diff --git a/scripts/settings/common/src/test/java/com/codename1/settings/SettingsThemeTest.java b/scripts/settings/common/src/test/java/com/codename1/settings/SettingsThemeTest.java index 44e7bd45a73..51b615d94c5 100644 --- a/scripts/settings/common/src/test/java/com/codename1/settings/SettingsThemeTest.java +++ b/scripts/settings/common/src/test/java/com/codename1/settings/SettingsThemeTest.java @@ -125,7 +125,12 @@ public void uiUsesDensityAwareThemeSizingInsteadOfFixedComponentDimensions() thr "Theme font sizes must use physical mm units so Retina density does not create miniature text."); assertTrue(source.contains("new TableLayout(1, 2)"), "The main content width should be responsive through TableLayout percentages."); - assertTrue(source.contains("new GridLayout(3, 2)"), + // Match the column count, not the row count. This asserted GridLayout(3, 2) + // and the Basic form has grown to five rows since; because this module's + // tests are skipped by default nothing reported the drift. The two columns + // are what makes the form responsive -- the row count is just how many + // fields there happen to be. + assertTrue(Pattern.compile("new GridLayout\\(\\d+, 2\\)").matcher(source).find(), "The Basic form should use a responsive two-column GridLayout."); assertTrue(source.contains("private Container configureToolbar()"), "Native desktop chrome should use a stable top-bar container, not a second Toolbar instance."); diff --git a/scripts/settings/pom.xml b/scripts/settings/pom.xml index ac7954b0357..24c27fa99d2 100644 --- a/scripts/settings/pom.xml +++ b/scripts/settings/pom.xml @@ -68,6 +68,11 @@ codenameone-javase ${cn1.version}
+ + com.codenameone + codenameone-build-hint-catalog + ${cn1.version} +
diff --git a/scripts/video-builder/common/codenameone_settings.properties b/scripts/video-builder/common/codenameone_settings.properties index b7f6775b36e..4dbecd58940 100644 --- a/scripts/video-builder/common/codenameone_settings.properties +++ b/scripts/video-builder/common/codenameone_settings.properties @@ -5,7 +5,4 @@ codename1.version=1.0 codename1.vendor=CodenameOne codename1.cssTheme=true codename1.arg.java.version=17 -codename1.arg.desktop.width=1280 -codename1.arg.desktop.height=720 -codename1.arg.desktop.titleBar=native codename1.kotlin=false diff --git a/scripts/video-builder/common/src/main/java/com/codename1/videobuilder/VideoBuilder.java b/scripts/video-builder/common/src/main/java/com/codename1/videobuilder/VideoBuilder.java index 00dc4e27788..5883947d9b8 100644 --- a/scripts/video-builder/common/src/main/java/com/codename1/videobuilder/VideoBuilder.java +++ b/scripts/video-builder/common/src/main/java/com/codename1/videobuilder/VideoBuilder.java @@ -37,8 +37,10 @@ import java.security.MessageDigest; import java.util.ArrayList; import java.util.List; +import com.codename1.annotations.buildhints.*; /** Codename One application lifecycle and CLI dispatcher. */ +@Desktop(height = 720, titleBar = DesktopTitleBar.NATIVE, width = 1280) public final class VideoBuilder { private Form current; diff --git a/tools/build-hint-bootstrap/README.md b/tools/build-hint-bootstrap/README.md new file mode 100644 index 00000000000..f27e5ef8641 --- /dev/null +++ b/tools/build-hint-bootstrap/README.md @@ -0,0 +1,23 @@ +# Build hint catalog bootstrap (one-off, archived) + +These scripts seeded `maven/build-hint-catalog` when the catalog was first +created. They mined every `getArg` call site in the builders for a hint's name +and default, imported the prose from the developer guide's hand-written build +hint table, and emitted the `BuildHints*.java` registration classes. + +**They are not part of any build and should not be re-run.** The catalog is the +source of truth now and is edited directly; `scripts/gen-build-hint-annotations.sh` +generates the annotations, the docs and the Settings schema *from* it. + +They are kept only to show where the catalog's contents came from. They read the +guide's original hand-written table from a `guide_old.asciidoc` that is +deliberately not committed — recover it from history if you ever need it: + +```bash +git show :docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc \ + > tools/build-hint-bootstrap/guide_old.asciidoc +``` + +Re-running them would overwrite hand-edits to the catalog. If you ever need to +re-derive an entry, read the miner instead: `scripts/build_hint_miner.py` is the +supported, tested version of the same extraction and is what the CI gate uses. diff --git a/tools/build-hint-bootstrap/curation.py b/tools/build-hint-bootstrap/curation.py new file mode 100644 index 00000000000..7ca8c27d14e --- /dev/null +++ b/tools/build-hint-bootstrap/curation.py @@ -0,0 +1,220 @@ +# The curated set: hints exposed as typed annotation attributes. +# +# name -> (group, attribute, enum-or-None, forced-type-or-None, forced-default-or-None) +# +# TYPE_OVERRIDES below carries the hints whose type cannot be inferred from a +# literal default -- the call site computes one -- but whose type is unambiguous +# in the code that reads it. Without them a boolean hint is exposed as a String +# attribute, which is barely better than the properties file. +# +# Every enum domain below was read off the code that consumes the hint, not +# guessed from a name or a doc sentence. Where the consumer accepts alias +# spellings (ios.themeMode takes "liquid" for "modern"), the enum exposes the +# canonical spelling only: on the annotation path an over-tight domain costs a +# fallback to the properties file, never a broken build, and the aliases stay +# reachable there. + +ENUMS = { + # HardeningPreflight.java:90 rejects anything else outright. + "HardenLevel": ["off", "standard", "aggressive", "paranoid"], + "HardenStrings": ["off", "constants", "all"], + "HardenControlFlow": ["off", "on"], + # BuildHintSchemaDefaults.registerNativeTheme + JavaSEPort.resolveAutoNativeTheme + "NativeThemeMode": ["modern", "legacy", "custom"], + "IosThemeMode": ["auto", "modern", "ios7", "legacy"], + "AndroidThemeMode": ["auto", "modern", "hololight", "legacy"], + # GenerateDesktopAppWrapperMojo.sanitizeTitleBarMode warns and silently + # falls back to "native" on anything else -- the exact silent-typo case. + "DesktopTitleBar": ["native", "custom", "toolbar"], + # IOSDependencyManager.fromHint throws on anything else. + "IosDependencyManager": ["auto", "cocoapods", "spm", "both", "none"], + # "one of ios, ipad, iphone (defaults to ios)" -- the guide states it and + # the value is passed straight through to ParparVM (IPhoneBuilder.java:4572). + "IosProjectType": ["ios", "ipad", "iphone"], + # The three values android:installLocation itself accepts. + "InstallLocation": ["auto", "internalOnly", "preferExternal"], +} + +CURATED = { + # ---- @Ios ------------------------------------------------------------- + "ios.newStorageLocation": ("IOS", "newStorageLocation", None, None, None), + "ios.deployment_target": ("IOS", "deploymentTarget", None, "VERSION", None), + "ios.minDeploymentTarget": ("IOS", "minDeploymentTarget", None, "VERSION", "6.0"), + "ios.teamId": ("IOS", "teamId", None, None, None), + "ios.includePush": ("IOS", "includePush", None, None, None), + "ios.add_libs": ("IOS", "addLibs", None, None, None), + "ios.pods": ("IOS", "pods", None, None, None), + "ios.pods.platform": ("IOS", "podsPlatform", None, "VERSION", None), + "ios.pods.sources": ("IOS", "podsSources", None, None, None), + "ios.applicationQueriesSchemes": ("IOS", "applicationQueriesSchemes", None, None, None), + "ios.objC": ("IOS", "objC", None, None, None), + "ios.plistInject": ("IOS", "plistInject", None, None, None), + "ios.glAppDelegateHeader": ("IOS", "glAppDelegateHeader", None, None, None), + "ios.beforeFinishLaunching": ("IOS", "beforeFinishLaunching", None, None, None), + "ios.themeMode": ("IOS", "themeMode", "IosThemeMode", None, None), + "ios.interface_orientation": ("IOS", "interfaceOrientation", None, None, None), + "ios.project_type": ("IOS", "projectType", "IosProjectType", None, None), + "ios.prerendered_icon": ("IOS", "prerenderedIcon", None, None, None), + "ios.uiscene": ("IOS", "uiscene", None, None, None), + "ios.urlScheme": ("IOS", "urlScheme", None, None, None), + "ios.dependencyManager": ("IOS", "dependencyManager", "IosDependencyManager", None, None), + "ios.bundleVersion": ("IOS", "bundleVersion", None, "VERSION", None), + "ios.spm.packages": ("IOS", "spmPackages", None, None, None), + # ---- @Android --------------------------------------------------------- + "android.min_sdk_version": ("ANDROID", "minSdkVersion", None, None, None), + "android.targetSDKVersion": ("ANDROID", "targetSDKVersion", None, None, None), + "android.buildToolsVersion": ("ANDROID", "buildToolsVersion", None, None, None), + "android.xpermissions": ("ANDROID", "xpermissions", None, None, None), + "android.xapplication": ("ANDROID", "xapplication", None, None, None), + "android.gradleDep": ("ANDROID", "gradleDep", None, None, None), + "android.proguardKeep": ("ANDROID", "proguardKeep", None, None, None), + "android.release": ("ANDROID", "release", None, None, None), + "android.debug": ("ANDROID", "debug", None, None, None), + "android.useAndroidX": ("ANDROID", "useAndroidX", None, None, None), + "android.licenseKey": ("ANDROID", "licenseKey", None, None, None), + "android.installLocation": ("ANDROID", "installLocation", "InstallLocation", None, None), + "android.activity.launchMode": ("ANDROID", "activityLaunchMode", None, None, None), + "and.themeMode": ("ANDROID", "themeMode", "AndroidThemeMode", None, None), + "android.appBundle": ("ANDROID", "appBundle", None, None, None), + "android.disableR8": ("ANDROID", "disableR8", None, None, None), + "android.enableProguard": ("ANDROID", "enableProguard", None, None, None), + "android.newFirebaseMessaging": ("ANDROID", "newFirebaseMessaging", None, None, None), + "android.multidex": ("ANDROID", "multidex", None, None, None), + "android.captureRecord": ("ANDROID", "captureRecord", None, None, None), + "android.hideStatusBar": ("ANDROID", "hideStatusBar", None, None, None), + "android.repositories": ("ANDROID", "repositories", None, None, None), + "android.topDependency": ("ANDROID", "topDependency", None, None, None), + "android.xgradle": ("ANDROID", "xgradle", None, None, None), + # ---- @Desktop --------------------------------------------------------- + "desktop.titleBar": ("DESKTOP", "titleBar", "DesktopTitleBar", None, None), + "desktop.interactiveScrollbars": ("DESKTOP", "interactiveScrollbars", None, None, None), + "desktop.width": ("DESKTOP", "width", None, "INT", None), + "desktop.height": ("DESKTOP", "height", None, "INT", None), + "desktop.resizable": ("DESKTOP", "resizable", None, None, None), + "desktop.fullscreen": ("DESKTOP", "fullscreen", None, None, None), + "desktop.adaptToRetina": ("DESKTOP", "adaptToRetina", None, None, None), + # ---- @Hardening ------------------------------------------------------- + "harden.level": ("HARDENING", "level", "HardenLevel", None, None), + "harden.strings": ("HARDENING", "strings", "HardenStrings", None, None), + "harden.controlFlow": ("HARDENING", "controlFlow", "HardenControlFlow", None, None), + "harden.rename": ("HARDENING", "rename", None, None, None), + "harden.keep": ("HARDENING", "keep", None, "TEXT_BLOCK", None), + "harden.allowUnhardenedLocalBuild": ("HARDENING", "allowUnhardenedLocalBuild", None, None, None), + # ---- @OnDeviceDebug --------------------------------------------------- + "ios.onDeviceDebug": ("ON_DEVICE_DEBUG", "ios", None, None, None), + "ios.onDeviceDebug.proxyHost": ("ON_DEVICE_DEBUG", "iosProxyHost", None, None, None), + "ios.onDeviceDebug.proxyPort": ("ON_DEVICE_DEBUG", "iosProxyPort", None, "INT", None), + "ios.onDeviceDebug.waitForAttach": ("ON_DEVICE_DEBUG", "iosWaitForAttach", None, None, None), + "android.onDeviceDebug": ("ON_DEVICE_DEBUG", "android", None, None, None), + # ---- @Build ----------------------------------------------------------- + "nativeTheme": ("GENERAL", "nativeTheme", "NativeThemeMode", None, None), + "gcm.sender_id": ("GENERAL", "gcmSenderId", None, None, None), + "facebook.appId": ("GENERAL", "facebookAppId", None, None, None), + "noExtraResources": ("GENERAL", "noExtraResources", None, None, None), +} + +# ios.NS*UsageDescription -> @IosPrivacy, attribute is the key minus "ios.NS" +# with a lowercased first letter; the UsageDescription suffix is kept so the +# plist key it maps to is mechanically recoverable. +PRIVACY_PREFIX = "ios.NS" + +# Hints whose default the mining cannot state in one value, resolved by reading +# the code rather than by picking whichever call site came first. +DEFAULT_NOTES = { + "android.debug": + "Defaults conditionally rather than to a fixed value: when android.release is on " + "it defaults to false, and when release is off it defaults to true, so a build " + "that selects neither still produces something installable " + "(AndroidGradleBuilder.java:447-451).", + "ios.minDeploymentTarget": + "The null and empty-string reads of this hint are presence checks; 6.0 is the " + "substantive default (IPhoneBuilder.java:4671).", +} + +# Prose for curated hints the main developer-guide table does not describe. +# Sourced from the feature chapters (App-Hardening.asciidoc) or read off the +# code that consumes the hint. The privacy strings are generated mechanically +# by BuildHintCodeGenerator and are not listed here. +DOC_OVERRIDES = { + "harden.level": + "Master switch for app hardening: off, standard, aggressive or paranoid. An " + "unrecognized value fails the build rather than being quietly treated as off.", + "harden.rename": + "Overrides symbol renaming independently of harden.level.", + "harden.strings": + "Overrides string obfuscation independently of harden.level: off, constants or all.", + "harden.controlFlow": + "Overrides control-flow obfuscation independently of harden.level.", + "harden.keep": + "Keep rules in ProGuard syntax, one per line, for classes that are resolved by " + "name at runtime and so cannot be found by the automatic analysis. Same syntax " + "as android.proguardKeep, so existing rules port directly. Rules are separated " + "by newlines only, because a semicolon is legal inside a rule body such as " + "{ *; }.", + "harden.allowUnhardenedLocalBuild": + "Permits a local or source build to run with hardening requested but not " + "applied. Without it such a build is refused, so a hardened app is never " + "shipped from a target that cannot actually harden it.", + "desktop.titleBar": + "How the desktop window is framed: native for the OS title bar and menu bar, " + "custom for an undecorated window with a Codename One drawn title bar, or " + "toolbar for the legacy in-app Toolbar. An unrecognized value falls back to " + "native with a warning.", + "desktop.interactiveScrollbars": + "Enables grab-able, click-to-page desktop scrollbars.", + "desktop.fullscreen": + "Starts the desktop build in full-screen mode.", + "ios.dependencyManager": + "Which native dependency manager to use: auto picks one from whichever of " + "ios.pods and ios.spm.packages is set, and cocoapods, spm or both require the " + "matching hint to be set. An unrecognized value fails the build.", + "ios.deployment_target": + "Minimum iOS version the build targets. Set it to the lowest iOS you actually " + "support; a higher value excludes older devices from the App Store listing.", + "ios.pods.sources": + "Extra CocoaPods spec repositories to search, in addition to the default trunk.", + "ios.spm.packages": + "Swift Package Manager packages to link, one per entry, each written as " + "identity|url|requirement.", + "android.appBundle": + "Produces an Android App Bundle (.aab) rather than an APK. Required for new " + "Play Store submissions.", + "android.buildToolsVersion": + "Android build-tools version. It also selects the compile SDK, so there is no " + "separate compile-SDK hint.", + "android.disableR8": + "Turns off R8, falling back to the older shrinker. Note that hardening requires " + "R8, so this conflicts with harden.level.", + "android.gradleDep": + "Gradle dependency statements to add to the app module, such as " + "implementation 'com.example:lib:1.0'.", + "android.topDependency": + "Statements added to the top-level Gradle build file rather than the app module.", + "android.repositories": + "Extra Gradle repositories to resolve dependencies from.", + "android.xgradle": + "Arbitrary text spliced into the generated app-module Gradle file.", + "android.hideStatusBar": + "Hides the Android status bar.", + "android.newFirebaseMessaging": + "Uses the current Firebase Cloud Messaging integration. Requires AndroidX and " + "Gradle 8.13 or newer.", +} + + +# hint -> (HintType, separator-or-None). Each verified at the call site, not guessed. +TYPE_OVERRIDES = { + # request.getArg(...).equals("true"), with a computed rather than literal default + "android.useAndroidX": ("BOOLEAN", None), # AndroidGradleBuilder.java:1169 + "android.appBundle": ("BOOLEAN", None), # AndroidGradleBuilder.java:1441 + "harden.rename": ("BOOLEAN", None), # hardenBoolArg(..., true) + # version numbers whose default is computed from the installed toolchain + "android.targetSDKVersion": ("INT", None), # AndroidGradleBuilder.java:1401 + "android.buildToolsVersion": ("VERSION", None), # AndroidGradleBuilder.java:1186 + # split by the consumer, so they are lists even though no merger entry exists + "ios.spm.packages": ("STRING_LIST", ";"), # IOSDependencyManager.java:119 split("[;]") + "ios.pods.sources": ("STRING_LIST", ","), # IPhoneBuilder.java:5159 split("[;,]") + # free text that is expected to span lines + "ios.beforeFinishLaunching": ("TEXT_BLOCK", None), + "ios.glAppDelegateHeader": ("TEXT_BLOCK", None), +} diff --git a/tools/build-hint-bootstrap/gen_catalog.py b/tools/build-hint-bootstrap/gen_catalog.py new file mode 100644 index 00000000000..e1b07755067 --- /dev/null +++ b/tools/build-hint-bootstrap/gen_catalog.py @@ -0,0 +1,267 @@ +#!/usr/bin/env python3 +"""One-time bootstrap: emit the BuildHints* registration classes.""" +import json, re, os, sys, collections + +ROOT = "/Users/shai/dev/cn6/CodenameOne" +SC = os.path.dirname(os.path.abspath(__file__)) +OUT = os.path.join(ROOT, "maven/build-hint-catalog/src/main/java/com/codename1/build/shared") +LICENSE = open(os.path.join(SC, "license.txt")).read() + +mined = json.load(open(os.path.join(SC, "mined.json"))) + +sys.path.insert(0, SC) +from curation import CURATED, ENUMS, PRIVACY_PREFIX, DEFAULT_NOTES, DOC_OVERRIDES, TYPE_OVERRIDES + + +def privacy_attr(name): + """ios.NSCameraUsageDescription -> cameraUsageDescription.""" + body = name[len(PRIVACY_PREFIX):] + return body[0].lower() + body[1:] + +# ---------------------------------------------------------------- doc prose +def load_docs(): + # The guide's inline table has been replaced by the generated include, so the + # prose no longer has a live source. Recover the pre-migration copy with + # git show :docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc + # This bootstrap is a one-off: the catalog is the source of truth now and is + # edited directly. + p = os.path.join(SC, "guide_old.asciidoc") + lines = open(p, encoding="utf-8").read().split("\n")[30:736] + docs, i = {}, 0 + while i < len(lines): + ln = lines[i] + m = re.fullmatch(r'\|([A-Za-z][A-Za-z0-9_.<>\-]*)', ln.strip()) + # a Vale/AsciiDoc // directive may sit between the name and its description + k = i + 1 + while k < len(lines) and lines[k].lstrip().startswith("//"): + k += 1 + if m and k < len(lines) and lines[k].startswith("|"): + body, j = [lines[k][1:]], k + 1 + while j < len(lines) and lines[j].strip() and not lines[j].startswith("|"): + body.append(lines[j]); j += 1 + docs[m.group(1)] = " ".join(x.strip() for x in body).strip() + i = j + else: + i += 1 + return docs + +DOCS = load_docs() +print(f"doc rows parsed: {len(DOCS)}", file=sys.stderr) + +def clean_doc(t): + t = re.sub(r'<<[^,>]*,\s*([^>]*)>>', r'\1', t) # <> -> text + t = re.sub(r'<<([^>]*)>>', r'\1', t) # <> -> anchor + t = re.sub(r'\s+', ' ', t).strip() + return t + +# separators are authoritative -- read off LibraryHintMerger +SEPARATORS = { + "android.gradleDep": ";", "gradleDependencies": "\n", "android.topDependency": "\n", + "android.repositories": "\n", "android.xgradle": "\n", "android.gradle.androidx": "\n", + "android.xgradle_default_config": "\n", "android.gradlePlugin": "\n", + "android.supportv4Dep": "\n", "android.proguardKeep": "\n", + "ios.pods": ",", "ios.applicationQueriesSchemes": ",", "ios.add_libs": ";", + # joins with a space, but it is an XML attribute fragment rather than a list + # the user thinks of as items, so it keeps HintType.XML -- see infer(). + "android.xapplication_attr": " ", +} +# Every entry above is a list the user edits as items; this one is not. +SEPARATOR_BUT_NOT_A_LIST = {"android.xapplication_attr"} +XML_HINTS = re.compile(r'^(android\.(xpermissions|xapplication|xmanifest|xactivity|' + r'xintent_filter|xqueries|xapplication_attr|xactivity_attr)|ios\.plistInject|' + r'ios\.entitlementsInject|.*Inject)$') + +ID_NAME = re.compile(r'(^|[._])([a-z]+_)?id$|Id$|_id$', re.I) + +def is_int_hint(name, lit): + """A digit default is only an int if it is arithmetic, not an identifier. + + facebook.appId defaults to a 15-digit Facebook app id: it overflows a Java + int and nothing ever adds to it. Such a hint is an opaque string. + """ + if ID_NAME.search(name): + return False + try: + v = int(lit) + except ValueError: + return False + return -2**31 <= v < 2**31 + + +def infer(name, defaults, doc): + if name in TYPE_OVERRIDES: + t, sep = TYPE_OVERRIDES[name] + lit = None + for x in defaults: + if x.startswith('"') and x.endswith('"'): + lit = x[1:-1]; break + if x in ("true", "false") or re.fullmatch(r'-?\d+', x): + lit = x; break + return t, lit, sep + d = [x for x in defaults if x not in ("", "null")] + lit = None + for x in d: + if x.startswith('"') and x.endswith('"'): + lit = x[1:-1]; break + if x in ("true", "false") or re.fullmatch(r'-?\d+', x): + lit = x; break + dl = doc.lower() + if name in SEPARATORS: + if name in SEPARATOR_BUT_NOT_A_LIST: + return "XML", lit, SEPARATORS[name] + return "STRING_LIST", lit, SEPARATORS[name] + if XML_HINTS.match(name): + return "XML", lit, "" + if lit in ("true", "false") or {x.strip('"') for x in d} <= {"true", "false"} and d: + return "BOOLEAN", lit, None + if lit is not None and re.fullmatch(r'-?\d+', lit) and is_int_hint(name, lit): + return "INT", lit, None + if "true/false" in dl or dl.startswith("boolean"): + return "BOOLEAN", lit, None + if lit is not None and re.fullmatch(r'\d+\.\d+(\.\d+)?', lit): + return "VERSION", lit, None + return "STRING", lit, None + +PLATFORM = [("android.", "android"), ("and.", "android"), ("ios.", "ios"), + ("macNative.", "mac"), ("desktop.mac.", "mac"), ("windows.", "windows"), + ("win.", "windows"), ("linux.", "linux"), ("javascript.", "javascript"), + ("desktop.", "desktop"), ("tvNative.", "tv"), ("watchNative.", "watch")] + +IOS_PRIVACY = re.compile(r'^ios\.NS.*UsageDescription$') +ODD = re.compile(r'^(ios\.onDeviceDebug|android\.onDeviceDebug$)') + +def group_of(name): + if IOS_PRIVACY.match(name): return "IOS_PRIVACY" + if ODD.match(name): return "ON_DEVICE_DEBUG" + for p, g in [("ios.", "IOS"), ("android.", "ANDROID"), ("and.", "ANDROID"), + ("desktop.", "DESKTOP"), ("macNative.", "MAC_NATIVE"), + ("windows.", "WINDOWS"), ("linux.", "LINUX"), + ("javascript.", "JAVASCRIPT"), ("tvNative.", "TV_NATIVE"), + ("watchNative.", "WATCH_NATIVE"), ("harden.", "HARDENING")]: + if name.startswith(p): return g + return "GENERAL" + +def platform_of(name): + for p, v in PLATFORM: + if name.startswith(p): return v + return "general" + +def jesc(s): + return (s.replace("\\", "\\\\").replace('"', '\\"') + .replace("\n", "\\n").replace("\t", "\\t").replace("\r", "")) + +def wrap(text, indent, width=88): + """Split a long Java string literal into concatenated chunks.""" + words, lines, cur = text.split(" "), [], "" + for w in words: + if len(cur) + len(w) + 1 > width and cur: + lines.append(cur); cur = w + else: + cur = (cur + " " + w).strip() + if cur: lines.append(cur) + if not lines: return '""' + if len(lines) == 1: return '"%s"' % jesc(lines[0]) + sep = "\n" + " " * indent + "+ " + return sep.join('"%s "' % jesc(l) if i < len(lines) - 1 else '"%s"' % jesc(l) + for i, l in enumerate(lines)) + +FILES = { + "BuildHintsIos": lambda n: group_of(n) in ("IOS", "IOS_PRIVACY"), + "BuildHintsAndroid": lambda n: group_of(n) == "ANDROID", + "BuildHintsApple": lambda n: group_of(n) in ("MAC_NATIVE", "TV_NATIVE", "WATCH_NATIVE"), + "BuildHintsDesktop": lambda n: group_of(n) in ("DESKTOP", "WINDOWS", "LINUX", "JAVASCRIPT"), + "BuildHintsGeneral": lambda n: group_of(n) in ("GENERAL", "HARDENING", "ON_DEVICE_DEBUG"), +} + +BLURB = { + "BuildHintsIos": "iOS build hints, including the Info.plist privacy strings.", + "BuildHintsAndroid": "Android build hints, including the {@code and.} override aliases.", + "BuildHintsApple": "macOS Catalyst, tvOS and watchOS native-slice build hints.", + "BuildHintsDesktop": "Desktop, native Windows, native Linux and JavaScript build hints.", + "BuildHintsGeneral": "Hints with no platform prefix, plus hardening and on-device debugging.", +} + +# A mined key ending in a dot is the constant half of a concatenation -- +# getArg("android.permission." + name) -- not a hint anyone can set. Cataloguing +# it would put a phantom row in the guide and a phantom entry in the Settings +# tool. Each one is covered by a dynamic family instead. +mined = {k: v for k, v in mined.items() if not k.endswith(".")} + +counts = collections.Counter() +for fname, pred in FILES.items(): + names = sorted(n for n in mined if pred(n)) + counts[fname] = len(names) + body = [] + for n in names: + defaults = [d for d, _, _ in mined[n]] + sites = sorted({os.path.basename(f)[:-5] for _, f, _ in mined[n]}) + doc = clean_doc(DOCS.get(n, "")) + if not doc and n in DOC_OVERRIDES: + doc = DOC_OVERRIDES[n] + if n in DEFAULT_NOTES: + if doc and not doc.rstrip().endswith((".", "!", "?")): + doc = doc.rstrip() + "." + doc = (doc + " " + DEFAULT_NOTES[n]).strip() + htype, lit, sep = infer(n, defaults, doc) + parts = [' h.add(new Hint("%s")' % jesc(n)] + g = group_of(n) + cur = CURATED.get(n) + enum_name = None + if g == "IOS_PRIVACY": + parts.append(' .annotatedAs(HintGroup.IOS_PRIVACY, "%s")' % privacy_attr(n)) + htype = "STRING" + elif cur: + cg, attr, enum_name, forced_type, forced_def = cur + parts.append(' .annotatedAs(HintGroup.%s, "%s")' % (cg, attr)) + if forced_type: + htype = forced_type + if forced_def is not None: + lit = forced_def + else: + parts.append(' .group(HintGroup.%s)' % g) + if enum_name: + vals = ", ".join('"%s"' % v for v in ENUMS[enum_name]) + parts.append(' .values("%s", %s)' % (enum_name, vals)) + if lit is not None and lit not in ENUMS[enum_name]: + lit = None + else: + parts.append(' .type(HintType.%s)' % htype) + if lit is not None and lit != "": + parts.append(' .def("%s")' % jesc(lit)) + if sep is not None: + parts.append(' .separator("%s")' % jesc(sep)) + parts.append(' .platform("%s")' % platform_of(n)) + parts.append(' .consumedBy(%s)' % ", ".join('"%s"' % s for s in sites)) + if doc: + parts.append(' .doc(%s)' % wrap(doc, 24)) + body.append("\n".join(parts) + ");") + + src = LICENSE + f'''package com.codename1.build.shared; + +import com.codename1.build.shared.BuildHints.Hint; + +import java.util.List; + +/** + * {BLURB[fname]} + * + *

Seeded by mining every {{@code getArg}} call site in the builders, so the + * name and the default match what the build actually reads. Curated entries + * carry an annotation attribute and, where the domain is provably closed, an + * enum; the rest are described but set through + * {{@code codenameone_settings.properties}}.

+ * + *

Split out of {{@link BuildHints}} because a single class initializer + * holding every entry would exceed the JVM's 64KB per-method limit.

+ */ +final class {fname} {{ + + private {fname}() {{ + }} + + static void register(List h) {{ +''' + "\n\n".join(body) + "\n }\n}\n" + open(os.path.join(OUT, fname + ".java"), "w").write(src) + +print("entries per file:", dict(counts), file=sys.stderr) +print("total:", sum(counts.values()), file=sys.stderr) diff --git a/tools/build-hint-bootstrap/gen_external.py b/tools/build-hint-bootstrap/gen_external.py new file mode 100644 index 00000000000..979fe6de47e --- /dev/null +++ b/tools/build-hint-bootstrap/gen_external.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +"""Emit BuildHintsExternal: hints the developer guide documents that no code in +this repository reads. Most are consumed by build-daemon lanes whose source is +not mirrored here, so their absence is not evidence they are dead -- which is +exactly why they are recorded rather than enforced.""" +import json, sys, os, re +SC = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, SC) +import gen_catalog as G + +ROOT = "/Users/shai/dev/cn6/CodenameOne" +OUT = os.path.join(ROOT, "maven/build-hint-catalog/src/main/java/com/codename1/build/shared") +LICENSE = open(os.path.join(SC, "license.txt")).read() + +mined = set(json.load(open(SC + "/mined.json"))) +PLACEHOLDER = re.compile(r'PERMISSION_NAME|[A-Z_]{4,}$|[<>]') + +names = sorted(k for k in G.DOCS + if k not in mined and not PLACEHOLDER.search(k) and "." in k or + (k not in mined and not PLACEHOLDER.search(k) and k.islower())) +names = sorted(set(n for n in names if not PLACEHOLDER.search(n))) + +body = [] +for n in names: + doc = G.clean_doc(G.DOCS[n]) + htype, lit, sep = G.infer(n, [], doc) + parts = [' h.add(new Hint("%s")' % G.jesc(n)] + parts.append(' .group(HintGroup.%s)' % G.group_of(n)) + parts.append(' .type(HintType.%s)' % htype) + if sep is not None: + parts.append(' .separator("%s")' % G.jesc(sep)) + parts.append(' .platform("%s")' % G.platform_of(n)) + parts.append(' .external()') + if doc: + parts.append(' .doc(%s)' % G.wrap(doc, 24)) + body.append("\n".join(parts) + ");") + +src = LICENSE + '''package com.codename1.build.shared; + +import com.codename1.build.shared.BuildHints.Hint; + +import java.util.List; + +/** + * Hints the developer guide documents that nothing in this repository reads. + * + *

Most are consumed by build-daemon lanes whose source is not mirrored here, + * so having no in-repo consumer is not evidence that a hint is dead. A few are + * probably genuinely obsolete. Recording the distinction as + * {@link Hint#isExternal()} keeps both the drift gate and the Settings tool + * honest: the gate does not demand a consumer for these, and the tool still + * offers them for editing.

+ * + *

They are deliberately not annotated. Exposing a hint as a typed attribute + * is a promise that setting it does something, and for these that promise + * cannot be checked from this repository.

+ */ +final class BuildHintsExternal { + + private BuildHintsExternal() { + } + + static void register(List h) { +''' + "\n\n".join(body) + "\n }\n}\n" +open(os.path.join(OUT, "BuildHintsExternal.java"), "w").write(src) +print("external entries:", len(names), file=sys.stderr) From d24353565a1c4b770ce06caf6740aee552034d31 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sat, 22 Aug 2026 21:41:23 +0300 Subject: [PATCH 02/23] Commit the catalog sources that .gitignore was swallowing `.gitignore` carries a repo-wide `**/build/*`. The catalog's package is `com.codename1.build.shared`, so all 13 of its sources sat under a path segment named `build` and `git add` silently skipped them. Only `pom.xml` was committed: the module built locally from the working tree and produced an empty jar in CI, which is why `codenameone-maven-plugin` then failed with `cannot find symbol` on `BuildHints` and nearly every job went red. The sibling `platform-feature-catalog` lives in the same package and is fine, because it was added before that rule existed -- tracked files stay tracked, so nothing ever pointed at the hazard. Un-ignore `build` when it is a Java package rather than a build output directory, with the rationale beside the rule so the next file added there is not lost the same way. `maven/core/build/*` and `CodenameOne/build/*` stay ignored. Also from review: - Every bare `open()` in the four Python scripts now uses a context manager, so the handle closes even if parsing or `json.dump` raises, and the writes state their encoding. - The generator no longer emits an IP literal as an annotation default. PMD reads `default "127.0.0.1"` as hardcoded configuration, and the default clause is documentation only -- the processor emits a hint solely for members the developer actually wrote -- so the value moves to the javadoc where it belongs. - Files the migration touched that never carried a copyright header now have the complete one. The archetype's `__mainName__.java` is excluded instead: it is a template for the user's own application class, and stamping a Codename One GPL header onto it would put our licence on their code. Co-Authored-By: Claude Opus 5 (1M context) --- .gitignore | 9 + .../annotations/buildhints/OnDeviceDebug.java | 2 +- .../codenameone/developerguide/DemoCode.java | 22 + .../shared/BuildHintAnnotationBinding.java | 216 +++ .../build/shared/BuildHintCodeGenerator.java | 746 +++++++++ .../codename1/build/shared/BuildHints.java | 386 +++++ .../build/shared/BuildHintsAndroid.java | 1445 +++++++++++++++++ .../build/shared/BuildHintsApple.java | 291 ++++ .../build/shared/BuildHintsDesktop.java | 345 ++++ .../build/shared/BuildHintsDynamic.java | 112 ++ .../build/shared/BuildHintsExternal.java | 547 +++++++ .../build/shared/BuildHintsGeneral.java | 437 +++++ .../codename1/build/shared/BuildHintsIos.java | 1203 ++++++++++++++ .../com/codename1/build/shared/HintGroup.java | 83 + .../com/codename1/build/shared/HintType.java | 57 + .../build/shared/BuildHintsTest.java | 319 ++++ scripts/build_hint_miner.py | 6 +- scripts/check-build-hint-catalog.py | 15 +- scripts/copyright-header-exclusions.txt | 1 + .../com/codenameone/fidelity/FidelityApp.java | 6 +- .../inputvalidation/InputValidationApp.java | 20 +- .../purchasetest/PurchaseTestApp.java | 22 + .../settings/hints/BuildHintCatalog.java | 22 + .../settings/hints/BuildHintMetadata.java | 22 + .../settings/project/ProjectBinding.java | 22 + .../settings/BuildHintCatalogTest.java | 22 + .../codename1/settings/SettingsThemeTest.java | 22 + tools/build-hint-bootstrap/gen_catalog.py | 12 +- tools/build-hint-bootstrap/gen_external.py | 9 +- 29 files changed, 6401 insertions(+), 20 deletions(-) create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintAnnotationBinding.java create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHints.java create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDynamic.java create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsExternal.java create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsIos.java create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/HintGroup.java create mode 100644 maven/build-hint-catalog/src/main/java/com/codename1/build/shared/HintType.java create mode 100644 maven/build-hint-catalog/src/test/java/com/codename1/build/shared/BuildHintsTest.java diff --git a/.gitignore b/.gitignore index 7665845fb72..29fe25c6425 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,15 @@ !maven/cn1app-archetype/src/main/resources/archetype-resources/.idea !maven/cn1app-archetype/src/main/resources/archetype-resources/.idea/** **/build/* +# ...but `build` is also a legitimate Java package name, and com.codename1.build.shared +# is where the catalogs shared with the build service live. Without these, a new file +# there is silently untracked: `git add` skips it, the module compiles locally from the +# working tree, and CI fails with "No sources to compile". The existing files in that +# package survive only because they were added before the rule above. +!**/src/main/java/**/build/ +!**/src/main/java/**/build/** +!**/src/test/java/**/build/ +!**/src/test/java/**/build/** **/dist/* *.zip CodenameOneDesigner/src/version.properties diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java b/CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java index 14a467ace1e..ef5fca7085a 100644 --- a/CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java +++ b/CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java @@ -63,7 +63,7 @@ /// proxy. Default `127.0.0.1` (correct for the native iOS simulator). For a /// physical device, set this to the developer laptop's LAN IP. Has no effect /// unless `ios.onDeviceDebug=true`. - String iosProxyHost() default "127.0.0.1"; + String iosProxyHost() default ""; /// TCP port on `ios.onDeviceDebug.proxyHost` where the proxy is listening for /// the device. Default `55333`. Has no effect unless `ios.onDeviceDebug=true`. diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java index 6ed5a799391..02cb53f3755 100644 --- a/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java +++ b/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ package com.codenameone.developerguide; import com.codename1.system.Lifecycle; diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintAnnotationBinding.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintAnnotationBinding.java new file mode 100644 index 00000000000..73e3e6081ed --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintAnnotationBinding.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Maps a build hint annotation back to the hint it sets. + * + *

The annotation processor reads bytecode, where an annotation member is + * just a name and an enum value is just a constant name. It must not + * re-derive the hint name or the wire value from those strings: the folding + * rule would then exist in two places, and a builder silently falls back to + * its default on a value it does not recognise, so a mismatch would be + * invisible. This table is generated from the same catalog as the + * annotations, so the two cannot drift.

+ * + *

Generated by BuildHintCodeGenerator. Do not edit by hand.

+ */ +public final class BuildHintAnnotationBinding { + + /** JVM descriptor of an annotation type, by its simple name. */ + private static final Map DESCRIPTORS = + new HashMap(); + /** "#" to hint name. */ + private static final Map HINTS = new HashMap(); + /** "#" to the value the build receives. */ + private static final Map WIRE = new HashMap(); + + static { + DESCRIPTORS.put("IosPrivacy", "Lcom/codename1/annotations/buildhints/IosPrivacy;"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#calendarsFullAccessUsageDescription", "ios.NSCalendarsFullAccessUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#calendarsUsageDescription", "ios.NSCalendarsUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#calendarsWriteOnlyAccessUsageDescription", "ios.NSCalendarsWriteOnlyAccessUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#cameraUsageDescription", "ios.NSCameraUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#healthShareUsageDescription", "ios.NSHealthShareUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#healthUpdateUsageDescription", "ios.NSHealthUpdateUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#localNetworkUsageDescription", "ios.NSLocalNetworkUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#locationAlwaysAndWhenInUseUsageDescription", "ios.NSLocationAlwaysAndWhenInUseUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#locationAlwaysUsageDescription", "ios.NSLocationAlwaysUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#locationWhenInUseUsageDescription", "ios.NSLocationWhenInUseUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#microphoneUsageDescription", "ios.NSMicrophoneUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#remindersFullAccessUsageDescription", "ios.NSRemindersFullAccessUsageDescription"); + HINTS.put("Lcom/codename1/annotations/buildhints/IosPrivacy;#remindersUsageDescription", "ios.NSRemindersUsageDescription"); + DESCRIPTORS.put("Ios", "Lcom/codename1/annotations/buildhints/Ios;"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#addLibs", "ios.add_libs"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#applicationQueriesSchemes", "ios.applicationQueriesSchemes"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#beforeFinishLaunching", "ios.beforeFinishLaunching"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#bundleVersion", "ios.bundleVersion"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#dependencyManager", "ios.dependencyManager"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#deploymentTarget", "ios.deployment_target"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#glAppDelegateHeader", "ios.glAppDelegateHeader"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#includePush", "ios.includePush"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#interfaceOrientation", "ios.interface_orientation"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#minDeploymentTarget", "ios.minDeploymentTarget"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#newStorageLocation", "ios.newStorageLocation"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#objC", "ios.objC"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#plistInject", "ios.plistInject"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#pods", "ios.pods"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#podsPlatform", "ios.pods.platform"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#podsSources", "ios.pods.sources"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#prerenderedIcon", "ios.prerendered_icon"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#projectType", "ios.project_type"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#spmPackages", "ios.spm.packages"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#teamId", "ios.teamId"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#themeMode", "ios.themeMode"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#uiscene", "ios.uiscene"); + HINTS.put("Lcom/codename1/annotations/buildhints/Ios;#urlScheme", "ios.urlScheme"); + DESCRIPTORS.put("Android", "Lcom/codename1/annotations/buildhints/Android;"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#activityLaunchMode", "android.activity.launchMode"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#appBundle", "android.appBundle"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#buildToolsVersion", "android.buildToolsVersion"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#captureRecord", "android.captureRecord"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#debug", "android.debug"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#disableR8", "android.disableR8"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#enableProguard", "android.enableProguard"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#gradleDep", "android.gradleDep"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#hideStatusBar", "android.hideStatusBar"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#installLocation", "android.installLocation"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#licenseKey", "android.licenseKey"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#minSdkVersion", "android.min_sdk_version"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#multidex", "android.multidex"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#newFirebaseMessaging", "android.newFirebaseMessaging"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#proguardKeep", "android.proguardKeep"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#release", "android.release"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#repositories", "android.repositories"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#targetSDKVersion", "android.targetSDKVersion"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#themeMode", "and.themeMode"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#topDependency", "android.topDependency"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#useAndroidX", "android.useAndroidX"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#xapplication", "android.xapplication"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#xgradle", "android.xgradle"); + HINTS.put("Lcom/codename1/annotations/buildhints/Android;#xpermissions", "android.xpermissions"); + DESCRIPTORS.put("Desktop", "Lcom/codename1/annotations/buildhints/Desktop;"); + HINTS.put("Lcom/codename1/annotations/buildhints/Desktop;#adaptToRetina", "desktop.adaptToRetina"); + HINTS.put("Lcom/codename1/annotations/buildhints/Desktop;#fullscreen", "desktop.fullscreen"); + HINTS.put("Lcom/codename1/annotations/buildhints/Desktop;#height", "desktop.height"); + HINTS.put("Lcom/codename1/annotations/buildhints/Desktop;#interactiveScrollbars", "desktop.interactiveScrollbars"); + HINTS.put("Lcom/codename1/annotations/buildhints/Desktop;#resizable", "desktop.resizable"); + HINTS.put("Lcom/codename1/annotations/buildhints/Desktop;#titleBar", "desktop.titleBar"); + HINTS.put("Lcom/codename1/annotations/buildhints/Desktop;#width", "desktop.width"); + DESCRIPTORS.put("OnDeviceDebug", "Lcom/codename1/annotations/buildhints/OnDeviceDebug;"); + HINTS.put("Lcom/codename1/annotations/buildhints/OnDeviceDebug;#android", "android.onDeviceDebug"); + HINTS.put("Lcom/codename1/annotations/buildhints/OnDeviceDebug;#ios", "ios.onDeviceDebug"); + HINTS.put("Lcom/codename1/annotations/buildhints/OnDeviceDebug;#iosProxyHost", "ios.onDeviceDebug.proxyHost"); + HINTS.put("Lcom/codename1/annotations/buildhints/OnDeviceDebug;#iosProxyPort", "ios.onDeviceDebug.proxyPort"); + HINTS.put("Lcom/codename1/annotations/buildhints/OnDeviceDebug;#iosWaitForAttach", "ios.onDeviceDebug.waitForAttach"); + DESCRIPTORS.put("Build", "Lcom/codename1/annotations/buildhints/Build;"); + HINTS.put("Lcom/codename1/annotations/buildhints/Build;#facebookAppId", "facebook.appId"); + HINTS.put("Lcom/codename1/annotations/buildhints/Build;#gcmSenderId", "gcm.sender_id"); + HINTS.put("Lcom/codename1/annotations/buildhints/Build;#nativeTheme", "nativeTheme"); + HINTS.put("Lcom/codename1/annotations/buildhints/Build;#noExtraResources", "noExtraResources"); + DESCRIPTORS.put("Hardening", "Lcom/codename1/annotations/buildhints/Hardening;"); + HINTS.put("Lcom/codename1/annotations/buildhints/Hardening;#allowUnhardenedLocalBuild", "harden.allowUnhardenedLocalBuild"); + HINTS.put("Lcom/codename1/annotations/buildhints/Hardening;#controlFlow", "harden.controlFlow"); + HINTS.put("Lcom/codename1/annotations/buildhints/Hardening;#keep", "harden.keep"); + HINTS.put("Lcom/codename1/annotations/buildhints/Hardening;#level", "harden.level"); + HINTS.put("Lcom/codename1/annotations/buildhints/Hardening;#rename", "harden.rename"); + HINTS.put("Lcom/codename1/annotations/buildhints/Hardening;#strings", "harden.strings"); + + WIRE.put("AndroidThemeMode#AUTO", "auto"); + WIRE.put("AndroidThemeMode#MODERN", "modern"); + WIRE.put("AndroidThemeMode#HOLOLIGHT", "hololight"); + WIRE.put("AndroidThemeMode#LEGACY", "legacy"); + WIRE.put("DesktopTitleBar#NATIVE", "native"); + WIRE.put("DesktopTitleBar#CUSTOM", "custom"); + WIRE.put("DesktopTitleBar#TOOLBAR", "toolbar"); + WIRE.put("HardenControlFlow#OFF", "off"); + WIRE.put("HardenControlFlow#ON", "on"); + WIRE.put("HardenLevel#OFF", "off"); + WIRE.put("HardenLevel#STANDARD", "standard"); + WIRE.put("HardenLevel#AGGRESSIVE", "aggressive"); + WIRE.put("HardenLevel#PARANOID", "paranoid"); + WIRE.put("HardenStrings#OFF", "off"); + WIRE.put("HardenStrings#CONSTANTS", "constants"); + WIRE.put("HardenStrings#ALL", "all"); + WIRE.put("InstallLocation#AUTO", "auto"); + WIRE.put("InstallLocation#INTERNAL_ONLY", "internalOnly"); + WIRE.put("InstallLocation#PREFER_EXTERNAL", "preferExternal"); + WIRE.put("IosDependencyManager#AUTO", "auto"); + WIRE.put("IosDependencyManager#COCOAPODS", "cocoapods"); + WIRE.put("IosDependencyManager#SPM", "spm"); + WIRE.put("IosDependencyManager#BOTH", "both"); + WIRE.put("IosDependencyManager#NONE", "none"); + WIRE.put("IosProjectType#IOS", "ios"); + WIRE.put("IosProjectType#IPAD", "ipad"); + WIRE.put("IosProjectType#IPHONE", "iphone"); + WIRE.put("IosThemeMode#AUTO", "auto"); + WIRE.put("IosThemeMode#MODERN", "modern"); + WIRE.put("IosThemeMode#IOS7", "ios7"); + WIRE.put("IosThemeMode#LEGACY", "legacy"); + WIRE.put("NativeThemeMode#MODERN", "modern"); + WIRE.put("NativeThemeMode#LEGACY", "legacy"); + WIRE.put("NativeThemeMode#CUSTOM", "custom"); + } + + private BuildHintAnnotationBinding() { + } + + /** Every build hint annotation descriptor, in JVM internal form. */ + public static java.util.Collection descriptors() { + return Collections.unmodifiableCollection(DESCRIPTORS.values()); + } + + /** + * The hint an annotation member sets. + * + * @param descriptor the annotation's JVM descriptor + * @param member the annotation member name + * @return the bare hint name, or null when the pair is not a build hint + */ + public static String hintFor(String descriptor, String member) { + return HINTS.get(descriptor + "#" + member); + } + + /** + * The value the build receives for an enum constant. + * + * @param enumDescriptorOrName the enum type, as a descriptor or a simple name + * @param constant the constant name as it appears in the class file + * @return the wire value, or null when the constant is unknown + */ + public static String wireValue(String enumDescriptorOrName, String constant) { + String simple = enumDescriptorOrName; + int slash = simple.lastIndexOf('/'); + if (slash >= 0) { + simple = simple.substring(slash + 1); + } + if (simple.endsWith(";")) { + simple = simple.substring(0, simple.length() - 1); + } + return WIRE.get(simple + "#" + constant); + } +} diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java new file mode 100644 index 00000000000..9b130800487 --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java @@ -0,0 +1,746 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.FileOutputStream; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * Generates the {@code com.codename1.annotations.build} annotation types from + * {@link BuildHints}, plus the binding table the annotation processor reads + * back. + * + *

The generated sources are checked in rather than produced into + * {@code target/}. {@code CodenameOne/src} is compiled by four independent + * front ends -- the Maven core module, the Ant/NetBeans project, IntelliJ and + * {@code ant core} -- and generating into {@code target/} reaches exactly one + * of them. The failure mode is not a build error but a jar-identity split, + * where {@code mvn install} and {@code ant core} produce different + * {@code codenameone-core.jar}s. Checked-in sources also mean {@code @Ios(} + * autocompletes in every IDE, which is the entire point of the feature.

+ * + *

Run through {@code scripts/gen-build-hint-annotations.sh}; CI re-runs it + * with {@code --check} and fails on any diff.

+ */ +public final class BuildHintCodeGenerator { + + private static final String LICENSE = + "/*\n" + + " * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.\n" + + " * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n" + + " * This code is free software; you can redistribute it and/or modify it\n" + + " * under the terms of the GNU General Public License version 2 only, as\n" + + " * published by the Free Software Foundation. Codename One designates this\n" + + " * particular file as subject to the \"Classpath\" exception as provided\n" + + " * by Oracle in the LICENSE file that accompanied this code.\n" + + " *\n" + + " * This code is distributed in the hope that it will be useful, but WITHOUT\n" + + " * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n" + + " * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n" + + " * version 2 for more details (a copy is included in the LICENSE file that\n" + + " * accompanied this code).\n" + + " *\n" + + " * You should have received a copy of the GNU General Public License version\n" + + " * 2 along with this work; if not, write to the Free Software Foundation,\n" + + " * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n" + + " *\n" + + " * Please contact Codename One through http://www.codenameone.com/ if you\n" + + " * need additional information or have any questions.\n" + + " */\n"; + + private static final String GENERATED_NOTE = + "/// Generated from com.codename1.build.shared.BuildHints by\n" + + "/// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and\n" + + "/// re-run scripts/gen-build-hint-annotations.sh.\n"; + + // NOT ...annotations.build: .gitignore carries a repo-wide **/build/* rule, + // which would silently make every generated source uncommittable and leave + // the CI drift gate with nothing to compare. + private static final String PKG = "com.codename1.annotations.buildhints"; + private static final String PKG_PATH = "com/codename1/annotations/buildhints"; + + private BuildHintCodeGenerator() { + } + + /** + * @param args annotation source root, the catalog source root for the + * generated binding table, and optionally one or more markdown + * files carrying a generated build hint table + */ + public static void main(String[] args) throws IOException { + if (args.length < 2) { + System.err.println("usage: BuildHintCodeGenerator " + + " [markdown-file...]"); + System.exit(2); + } + File annRoot = new File(args[0], PKG_PATH); + File catalogRoot = new File(args[1], "com/codename1/build/shared"); + if (!annRoot.isDirectory() && !annRoot.mkdirs()) { + throw new IOException("Could not create " + annRoot); + } + + Map> byGroup = + new LinkedHashMap>(); + Map enums = new TreeMap(); + for (BuildHints.Hint h : BuildHints.entries()) { + if (!h.isAnnotated()) { + continue; + } + List list = byGroup.get(h.group()); + if (list == null) { + list = new ArrayList(); + byGroup.put(h.group(), list); + } + list.add(h); + if (h.type() == HintType.ENUM) { + BuildHints.Hint previous = enums.put(h.enumName(), h); + if (previous != null && !previous.values().equals(h.values())) { + throw new IllegalStateException("Enum " + h.enumName() + + " is declared with two different domains: " + + previous.name() + " and " + h.name()); + } + } + } + + Set written = new LinkedHashSet(); + for (Map.Entry> e : byGroup.entrySet()) { + Collections.sort(e.getValue(), new Comparator() { + public int compare(BuildHints.Hint a, BuildHints.Hint b) { + return a.attr().compareTo(b.attr()); + } + }); + String name = e.getKey().annotationSimpleName(); + write(new File(annRoot, name + ".java"), annotationSource(e.getKey(), e.getValue())); + written.add(name + ".java"); + } + for (Map.Entry e : enums.entrySet()) { + write(new File(annRoot, e.getKey() + ".java"), enumSource(e.getKey(), e.getValue())); + written.add(e.getKey() + ".java"); + } + write(new File(annRoot, "package-info.java"), packageInfoSource(byGroup)); + written.add("package-info.java"); + + // A group that loses its last annotated hint must not leave a stale + // annotation type behind: it would still compile and still be settable, + // and it would write a hint nothing reads. + File[] existing = annRoot.listFiles(); + if (existing != null) { + for (File f : existing) { + if (f.getName().endsWith(".java") && !written.contains(f.getName()) && !f.delete()) { + throw new IOException("Could not remove stale generated file " + f); + } + } + } + + write(new File(catalogRoot, "BuildHintAnnotationBinding.java"), bindingSource(byGroup, enums)); + for (int i = 2; i < args.length; i++) { + File target = new File(args[i]); + if (target.getName().endsWith(".md")) { + rewriteMarkdown(target, byGroup); + } else if (target.getName().endsWith(".adoc") || target.getName().endsWith(".asciidoc")) { + write(target, asciidocTable()); + } else { + write(new File(target, "com/codename1/impl/javase/BuildHintCatalogDefaults.java"), + simulatorSchemaSource(byGroup)); + } + } + System.out.println("cn1: generated " + written.size() + " source(s) under " + annRoot); + } + + private static String javaType(BuildHints.Hint h) { + switch (h.type()) { + case BOOLEAN: return "boolean"; + case INT: return "int"; + case ENUM: return h.enumName(); + case STRING_LIST: return "String[]"; + default: return "String"; + } + } + + private static String defaultClause(BuildHints.Hint h) { + String d = h.def(); + switch (h.type()) { + case BOOLEAN: + return "true".equals(d) ? "true" : "false"; + case INT: + if (d != null && d.length() > 0) { + try { + return String.valueOf(Integer.parseInt(d.trim())); + } catch (NumberFormatException ignored) { + // fall through to zero + } + } + return "0"; + case ENUM: + String constant = d != null && h.values().contains(d) + ? enumConstant(d) : enumConstant(h.values().get(0)); + return h.enumName() + "." + constant; + case STRING_LIST: + return "{}"; + default: + // A literal IP address in generated source reads to a static analyser + // as hardcoded configuration (PMD AvoidUsingHardCodedIP), and it is not + // load-bearing here: the annotation's default clause is documentation + // only, since the processor emits a hint solely for members the + // developer actually wrote. The real default stays in the javadoc. + if (d != null && LOOKS_LIKE_IP.matcher(d).matches()) { + return "\"\""; + } + return "\"" + esc(d == null ? "" : d) + "\""; + } + } + + private static final java.util.regex.Pattern LOOKS_LIKE_IP = + java.util.regex.Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3}|::1|[0-9a-fA-F:]*:[0-9a-fA-F:]+"); + + /** Wire value to Java enum constant: {@code internalOnly} to INTERNAL_ONLY. */ + static String enumConstant(String wire) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < wire.length(); i++) { + char c = wire.charAt(i); + if (Character.isUpperCase(c) && sb.length() > 0 + && Character.isLowerCase(wire.charAt(i - 1))) { + sb.append('_'); + } + sb.append(Character.isLetterOrDigit(c) ? Character.toUpperCase(c) : '_'); + } + String out = sb.toString(); + return Character.isDigit(out.charAt(0)) ? "V" + out : out; + } + + private static String annotationSource(HintGroup group, List hints) { + StringBuilder sb = new StringBuilder(LICENSE); + sb.append("package ").append(PKG).append(";\n\n"); + sb.append("import java.lang.annotation.ElementType;\n"); + sb.append("import java.lang.annotation.Retention;\n"); + sb.append("import java.lang.annotation.RetentionPolicy;\n"); + sb.append("import java.lang.annotation.Target;\n\n"); + sb.append(doc(groupBlurb(group), "")); + sb.append("///\n"); + sb.append(doc("Place this on your application's main class -- the class named by " + + "`codename1.mainName`. An attribute you do not set is not written at all, " + + "so the builder's own default applies; the values shown here are that " + + "default, for reference.", "")); + sb.append("///\n"); + sb.append(GENERATED_NOTE); + sb.append("@Retention(RetentionPolicy.CLASS)\n"); + sb.append("@Target(ElementType.TYPE)\n"); + sb.append("public @interface ").append(group.annotationSimpleName()).append(" {\n"); + for (int i = 0; i < hints.size(); i++) { + BuildHints.Hint h = hints.get(i); + sb.append("\n"); + String text = h.doc(); + if (text == null || text.length() == 0) { + text = group == HintGroup.IOS_PRIVACY + ? "The text iOS shows when the app first asks for " + + plistSubject(h.name()) + ". It becomes the `" + + h.name().substring("ios.".length()) + + "` key in `Info.plist`. The App Store rejects an app that " + + "touches this resource without one." + : "Sets the `" + h.name() + "` build hint."; + } + sb.append(doc(text, " ")); + if (h.type() == HintType.STRING_LIST) { + sb.append(doc("Values are joined with `" + visible(h.separator()) + + "` when the hint is written.", " ")); + } + if (h.deprecated() != null) { + sb.append(" ///\n"); + sb.append(doc("Deprecated. " + h.deprecated(), " ")); + sb.append(" @Deprecated\n"); + } + sb.append(" ").append(javaType(h)).append(" ").append(h.attr()) + .append("() default ").append(defaultClause(h)).append(";\n"); + } + sb.append("}\n"); + return sb.toString(); + } + + /// Turns ios.NSCameraUsageDescription into "the camera", so the generated + /// sentence reads naturally rather than repeating the plist key. + private static String plistSubject(String hintName) { + String body = hintName.substring("ios.NS".length()); + if (body.endsWith("UsageDescription")) { + body = body.substring(0, body.length() - "UsageDescription".length()); + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < body.length(); i++) { + char c = body.charAt(i); + if (i > 0 && Character.isUpperCase(c) && !Character.isUpperCase(body.charAt(i - 1))) { + sb.append(' '); + } + sb.append(i == 0 ? Character.toLowerCase(c) : c); + } + return "the " + sb.toString().toLowerCase(); + } + + private static String groupBlurb(HintGroup g) { + switch (g) { + case IOS: return "iOS build hints, checked by the compiler."; + case ANDROID: return "Android build hints, checked by the compiler."; + case DESKTOP: return "Desktop build hints, checked by the compiler."; + case HARDENING: return "App hardening build hints, checked by the compiler."; + case ON_DEVICE_DEBUG: return "On-device debugging build hints for iOS and Android."; + case IOS_PRIVACY: return "iOS `Info.plist` privacy usage descriptions. Set the one " + + "for every protected resource your app touches: the build server accepts " + + "an app without them, and the App Store rejects it."; + case GENERAL: return "Build hints that are not specific to one platform."; + default: return g.annotationSimpleName() + " build hints."; + } + } + + private static String enumSource(String name, BuildHints.Hint origin) { + StringBuilder sb = new StringBuilder(LICENSE); + sb.append("package ").append(PKG).append(";\n\n"); + sb.append(doc("Accepted values of the `" + origin.name() + "` build hint.", "")); + sb.append("///\n"); + sb.append(doc("Each constant carries the string the build actually receives, which is " + + "not always the constant's own name.", "")); + sb.append("///\n"); + sb.append(GENERATED_NOTE); + sb.append("public enum ").append(name).append(" {\n"); + List values = origin.values(); + List labels = origin.valueLabels(); + for (int i = 0; i < values.size(); i++) { + String v = values.get(i); + if (i < labels.size()) { + sb.append(doc(labels.get(i), " ")); + } + sb.append(" ").append(enumConstant(v)).append("(\"").append(esc(v)).append("\")"); + sb.append(i == values.size() - 1 ? ";\n" : ",\n"); + } + sb.append("\n private final String wire;\n\n"); + sb.append(" ").append(name).append("(String wire) {\n"); + sb.append(" this.wire = wire;\n }\n\n"); + sb.append(doc("The value written into the build hint.", " ")); + sb.append(" public String wireValue() {\n return wire;\n }\n}\n"); + return sb.toString(); + } + + private static String packageInfoSource(Map> byGroup) { + StringBuilder sb = new StringBuilder(LICENSE); + sb.append(doc("Build hints expressed as annotations, so the compiler checks them.", "")); + sb.append("///\n"); + sb.append(doc("A build hint used to be a `codename1.arg.=` line in " + + "`codenameone_settings.properties`. Nothing validated it, so a misspelled " + + "name was copied into the build request, never read, and silently dropped: " + + "the build stayed green and the setting simply did nothing. Written as an " + + "annotation the same mistake is an unknown symbol, a wrong value type is a " + + "type error, and a value outside a hint's supported set is an unknown enum " + + "constant.", "")); + sb.append("///\n"); + sb.append(doc("Put the annotations on your application's main class:", "")); + sb.append("///\n"); + sb.append("/// ```java\n"); + sb.append("/// @Ios(newStorageLocation = true, themeMode = IosThemeMode.MODERN)\n"); + sb.append("/// @Android(themeMode = AndroidThemeMode.MODERN)\n"); + sb.append("/// @Desktop(titleBar = DesktopTitleBar.NATIVE)\n"); + sb.append("/// public class MyApplication {\n"); + sb.append("/// }\n"); + sb.append("/// ```\n"); + sb.append("///\n"); + sb.append(doc("These annotations cover the hints most applications set. The rest, and " + + "the open-ended families such as `android.permission.` that an " + + "annotation cannot express, are still set in " + + "`codenameone_settings.properties`, which continues to work exactly as " + + "before. Setting the same hint in both places is a build error.", "")); + sb.append("///\n"); + sb.append(GENERATED_NOTE); + sb.append("package ").append(PKG).append(";\n"); + return sb.toString(); + } + + private static String bindingSource(Map> byGroup, + Map enums) { + StringBuilder sb = new StringBuilder(LICENSE); + sb.append("package com.codename1.build.shared;\n\n"); + sb.append("import java.util.Collections;\n"); + sb.append("import java.util.HashMap;\n"); + sb.append("import java.util.Map;\n\n"); + sb.append("/**\n"); + sb.append(" * Maps a build hint annotation back to the hint it sets.\n"); + sb.append(" *\n"); + sb.append(" *

The annotation processor reads bytecode, where an annotation member is\n"); + sb.append(" * just a name and an enum value is just a constant name. It must not\n"); + sb.append(" * re-derive the hint name or the wire value from those strings: the folding\n"); + sb.append(" * rule would then exist in two places, and a builder silently falls back to\n"); + sb.append(" * its default on a value it does not recognise, so a mismatch would be\n"); + sb.append(" * invisible. This table is generated from the same catalog as the\n"); + sb.append(" * annotations, so the two cannot drift.

\n"); + sb.append(" *\n"); + sb.append(" *

Generated by BuildHintCodeGenerator. Do not edit by hand.

\n"); + sb.append(" */\n"); + sb.append("public final class BuildHintAnnotationBinding {\n\n"); + sb.append(" /** JVM descriptor of an annotation type, by its simple name. */\n"); + sb.append(" private static final Map DESCRIPTORS =\n"); + sb.append(" new HashMap();\n"); + sb.append(" /** \"#\" to hint name. */\n"); + sb.append(" private static final Map HINTS = new HashMap();\n"); + sb.append(" /** \"#\" to the value the build receives. */\n"); + sb.append(" private static final Map WIRE = new HashMap();\n\n"); + sb.append(" static {\n"); + for (Map.Entry> e : byGroup.entrySet()) { + String simple = e.getKey().annotationSimpleName(); + String desc = "L" + PKG_PATH + "/" + simple + ";"; + sb.append(" DESCRIPTORS.put(\"").append(simple).append("\", \"") + .append(desc).append("\");\n"); + for (BuildHints.Hint h : e.getValue()) { + sb.append(" HINTS.put(\"").append(desc).append("#").append(h.attr()) + .append("\", \"").append(esc(h.name())).append("\");\n"); + } + } + sb.append("\n"); + for (Map.Entry e : enums.entrySet()) { + for (String v : e.getValue().values()) { + sb.append(" WIRE.put(\"").append(e.getKey()).append("#") + .append(enumConstant(v)).append("\", \"").append(esc(v)).append("\");\n"); + } + } + sb.append(" }\n\n"); + sb.append(" private BuildHintAnnotationBinding() {\n }\n\n"); + sb.append(" /** Every build hint annotation descriptor, in JVM internal form. */\n"); + sb.append(" public static java.util.Collection descriptors() {\n"); + sb.append(" return Collections.unmodifiableCollection(DESCRIPTORS.values());\n }\n\n"); + sb.append(" /**\n"); + sb.append(" * The hint an annotation member sets.\n"); + sb.append(" *\n"); + sb.append(" * @param descriptor the annotation's JVM descriptor\n"); + sb.append(" * @param member the annotation member name\n"); + sb.append(" * @return the bare hint name, or null when the pair is not a build hint\n"); + sb.append(" */\n"); + sb.append(" public static String hintFor(String descriptor, String member) {\n"); + sb.append(" return HINTS.get(descriptor + \"#\" + member);\n }\n\n"); + sb.append(" /**\n"); + sb.append(" * The value the build receives for an enum constant.\n"); + sb.append(" *\n"); + sb.append(" * @param enumDescriptorOrName the enum type, as a descriptor or a simple name\n"); + sb.append(" * @param constant the constant name as it appears in the class file\n"); + sb.append(" * @return the wire value, or null when the constant is unknown\n"); + sb.append(" */\n"); + sb.append(" public static String wireValue(String enumDescriptorOrName, String constant) {\n"); + sb.append(" String simple = enumDescriptorOrName;\n"); + sb.append(" int slash = simple.lastIndexOf('/');\n"); + sb.append(" if (slash >= 0) {\n"); + sb.append(" simple = simple.substring(slash + 1);\n }\n"); + sb.append(" if (simple.endsWith(\";\")) {\n"); + sb.append(" simple = simple.substring(0, simple.length() - 1);\n }\n"); + sb.append(" return WIRE.get(simple + \"#\" + constant);\n }\n"); + sb.append("}\n"); + return sb.toString(); + } + + /** + * The simulator's Build Hint editor schema for every annotated hint. + * + *

Emitted as a companion to the hand-written BuildHintSchemaDefaults + * rather than replacing it: that file carries carefully written labels and + * group descriptions for fifteen hints, and regenerating it would trade real + * prose for mechanical text. Its registrations run first and {@code set} does + * not overwrite, so anything it describes by hand wins and this fills in the + * rest.

+ * + *

Generated as source rather than read from the catalog jar at runtime + * because Ports/JavaSE is built by Ant as well as Maven, and the Ant build + * has a hand-maintained classpath that a new jar would have to be added to.

+ */ + private static String simulatorSchemaSource(Map> byGroup) { + StringBuilder sb = new StringBuilder(LICENSE); + sb.append("package com.codename1.impl.javase;\n\n"); + sb.append("/**\n"); + sb.append(" * Build Hint editor schema for every hint that has a build hint annotation.\n"); + sb.append(" *\n"); + sb.append(" *

Generated from com.codename1.build.shared.BuildHints by\n"); + sb.append(" * BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and re-run\n"); + sb.append(" * scripts/gen-build-hint-annotations.sh.

\n"); + sb.append(" *\n"); + sb.append(" *

Registered after {@link BuildHintSchemaDefaults}, whose hand-written\n"); + sb.append(" * entries take precedence because the shared setter never overwrites.

\n"); + sb.append(" */\n"); + sb.append("final class BuildHintCatalogDefaults {\n\n"); + sb.append(" private BuildHintCatalogDefaults() {\n }\n\n"); + sb.append(" static void register() {\n"); + for (Map.Entry> e : byGroup.entrySet()) { + String group = e.getKey().annotationSimpleName(); + sb.append("\n set(\"{{@").append(group).append("}}.label\", ") + .append(quote(groupLabel(e.getKey()))).append(");\n"); + for (BuildHints.Hint h : e.getValue()) { + String key = "{{#" + group + "#" + h.name() + "}}"; + sb.append(" set(\"").append(key).append(".label\", ") + .append(quote(humanize(h.attr()))).append(");\n"); + sb.append(" set(\"").append(key).append(".type\", \"") + .append(BuildHints.editorWidget(h.type())).append("\");\n"); + if (h.type() == HintType.ENUM) { + StringBuilder values = new StringBuilder(); + for (String v : h.values()) { + if (values.length() > 0) { + values.append(','); + } + values.append(v); + } + sb.append(" set(\"").append(key).append(".values\", \"") + .append(values).append("\");\n"); + } + if (h.doc() != null && h.doc().length() > 0) { + sb.append(" set(\"").append(key).append(".description\", ") + .append(quote(h.doc())).append(");\n"); + } + } + } + sb.append(" }\n\n"); + sb.append(" /** Idempotent setter: does not overwrite user or project-level metadata. */\n"); + sb.append(" private static void set(String suffix, String value) {\n"); + sb.append(" String key = \"codename1.arg.\" + suffix;\n"); + sb.append(" if (System.getProperty(key) == null) {\n"); + sb.append(" System.setProperty(key, value);\n }\n }\n}\n"); + return sb.toString(); + } + + /** + * The developer guide's build hint table. + * + *

The hand-written table it replaces had a Name and a Description column + * and nothing else, so the Settings tool had to guess each hint's type by + * string-matching the description prose. Generating it adds the type and the + * default the builders actually use, and means a hint added to a builder can + * no longer be missing from the guide.

+ */ + private static String asciidocTable() { + List all = new ArrayList(BuildHints.entries()); + Collections.sort(all, new Comparator() { + public int compare(BuildHints.Hint a, BuildHints.Hint b) { + int byPlatform = a.platform().compareTo(b.platform()); + return byPlatform != 0 ? byPlatform : a.name().compareTo(b.name()); + } + }); + StringBuilder sb = new StringBuilder(); + sb.append("// Generated from com.codename1.build.shared.BuildHints by\n"); + sb.append("// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and re-run\n"); + sb.append("// scripts/gen-build-hint-annotations.sh.\n"); + sb.append("//\n"); + sb.append("// The Annotation column names the compiler-checked form where one exists;\n"); + sb.append("// those hints can be written on the application's main class instead of in\n"); + sb.append("// codenameone_settings.properties.\n\n"); + sb.append("[cols=\"2,1,1,2,4\"]\n"); + sb.append("|===\n"); + sb.append("|Name |Type |Default |Annotation |Description\n\n"); + for (BuildHints.Hint h : all) { + // Dynamic families are listed too: their names are patterns rather than + // keys, but they are real settings a reader needs to find. + sb.append('|').append(h.name()).append('\n'); + sb.append('|').append(adocType(h)).append('\n'); + sb.append('|').append(h.def() == null || h.def().length() == 0 + ? "_(none)_" : "`" + h.def() + "`").append('\n'); + sb.append('|').append(h.isAnnotated() + ? "`@" + h.group().annotationSimpleName() + "(" + h.attr() + ")`" + : (h.isDynamic() ? "_(properties file only)_" : "_(none)_")).append('\n'); + String doc = h.doc(); + if (doc == null || doc.length() == 0) { + doc = h.isExternal() + ? "Consumed by the build service. Not read by anything in the framework " + + "repository, so there is no in-repo reference for it." + : ""; + } + sb.append('|').append(doc).append("\n\n"); + } + sb.append("|===\n"); + return sb.toString(); + } + + private static String adocType(BuildHints.Hint h) { + if (h.type() == HintType.ENUM) { + StringBuilder sb = new StringBuilder(); + for (String v : h.values()) { + sb.append(sb.length() == 0 ? "" : ", ").append('`').append(v).append('`'); + } + return sb.toString(); + } + if (h.type() == HintType.STRING_LIST) { + String sep = "\n".equals(h.separator()) ? "newline" : "`" + h.separator() + "`"; + return "list (" + sep + " delimited)"; + } + return h.type().name().toLowerCase(); + } + + private static String groupLabel(HintGroup g) { + switch (g) { + case IOS: return "iOS"; + case ANDROID: return "Android"; + case DESKTOP: return "Desktop"; + case HARDENING: return "App Hardening"; + case ON_DEVICE_DEBUG: return "On-Device Debugging"; + case IOS_PRIVACY: return "iOS Privacy Strings"; + case GENERAL: return "General"; + default: return g.annotationSimpleName(); + } + } + + /** newStorageLocation -> "New storage location". */ + private static String humanize(String attr) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < attr.length(); i++) { + char c = attr.charAt(i); + if (i > 0 && Character.isUpperCase(c) && !Character.isUpperCase(attr.charAt(i - 1))) { + sb.append(' ').append(Character.toLowerCase(c)); + } else { + sb.append(i == 0 ? Character.toUpperCase(c) : c); + } + } + return sb.toString(); + } + + /** Java string literal, wrapped so the generated line stays readable. */ + private static String quote(String s) { + return "\"" + esc(s) + "\""; + } + + private static final String MD_BEGIN = ""; + private static final String MD_END = ""; + + /** + * Rewrites the generated table inside a markdown file, between the marker + * comments, leaving the hand-written prose around it alone. + * + *

This exists because the file it targets is shipped to coding agents and + * was hand-maintained: it told them to set {@code android.xPermissions}, + * {@code android.minSdkVersion} and {@code android.sdkVersion}, none of which + * any builder reads. Generating the table from the catalog is the only way it + * stays true.

+ */ + private static void rewriteMarkdown(File file, Map> byGroup) + throws IOException { + if (!file.isFile()) { + throw new IOException("No such markdown file: " + file); + } + StringBuilder existing = new StringBuilder(); + java.io.BufferedReader r = new java.io.BufferedReader( + new java.io.InputStreamReader(new java.io.FileInputStream(file), "UTF-8")); + try { + String line; + while ((line = r.readLine()) != null) { + existing.append(line).append('\n'); + } + } finally { + r.close(); + } + String text = existing.toString(); + int begin = text.indexOf(MD_BEGIN); + int end = text.indexOf(MD_END); + if (begin < 0 || end < 0 || end < begin) { + throw new IOException(file + " has no generated-table markers"); + } + StringBuilder table = new StringBuilder(); + table.append(MD_BEGIN).append('\n'); + table.append("\n\n"); + for (Map.Entry> e : byGroup.entrySet()) { + table.append("### `@").append(e.getKey().annotationSimpleName()).append("`\n\n"); + table.append("| Attribute | Type | Build hint |\n"); + table.append("| --- | --- | --- |\n"); + for (BuildHints.Hint h : e.getValue()) { + table.append("| `").append(h.attr()).append("` | `") + .append(markdownType(h)).append("` | `codename1.arg.") + .append(h.name()).append("` |\n"); + } + table.append('\n'); + } + table.append(MD_END); + String out = text.substring(0, begin) + table + text.substring(end + MD_END.length()); + java.io.Writer w = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); + try { + w.write(out); + } finally { + w.close(); + } + } + + private static String markdownType(BuildHints.Hint h) { + if (h.type() == HintType.ENUM) { + StringBuilder sb = new StringBuilder(h.enumName()).append('.'); + List v = h.values(); + for (int i = 0; i < v.size(); i++) { + sb.append(i == 0 ? "" : "\\|").append(enumConstant(v.get(i))); + } + return sb.toString(); + } + return javaType(h); + } + + /** Wraps text as /// markdown doc comment lines. */ + private static String doc(String text, String indent) { + String clean = text.replace("@since", "since").replaceAll("\\s+", " ").trim(); + StringBuilder sb = new StringBuilder(); + StringBuilder line = new StringBuilder(); + for (String word : clean.split(" ")) { + if (line.length() > 0 && line.length() + word.length() + 1 > 76) { + sb.append(indent).append("/// ").append(line).append("\n"); + line.setLength(0); + } + if (line.length() > 0) { + line.append(' '); + } + line.append(word); + } + if (line.length() > 0) { + sb.append(indent).append("/// ").append(line).append("\n"); + } + return sb.toString(); + } + + private static String visible(String sep) { + if ("\n".equals(sep)) { + return "\\n"; + } + return sep; + } + + private static String esc(String s) { + return s.replace("\\", "\\\\").replace("\"", "\\\"") + .replace("\n", "\\n").replace("\t", "\\t").replace("\r", ""); + } + + private static void write(File f, String content) throws IOException { + File parent = f.getParentFile(); + if (parent != null && !parent.isDirectory() && !parent.mkdirs()) { + throw new IOException("Could not create " + parent); + } + Writer w = new OutputStreamWriter(new FileOutputStream(f), "UTF-8"); + try { + w.write(content); + } finally { + w.close(); + } + } +} diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHints.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHints.java new file mode 100644 index 00000000000..980cca3bbcd --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHints.java @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * The single source of truth for Codename One build hints. + * + *

A build hint is a {@code codename1.arg.=} entry that reaches + * a builder as {@code BuildRequest.getArg(name, default)}. Historically the set + * of hints was described in five places that drifted apart: a prose AsciiDoc + * table in the developer guide, a runtime scraper of that table in the Settings + * tool, a fifteen-entry schema in the simulator, a fourteen-entry separator map + * in the Maven plugin, and a hand-written reference shipped to coding agents. + * None of them was checked against the builders, so a hint could be documented + * and unread, or read and undocumented, or simply misspelled in the reference + * with nothing to catch it.

+ * + *

This table replaces all five. It is Java rather than a data file because + * its consumers span five classpaths with no JSON library in common — the + * Java 5 core, the Java 7 JavaSE port, the Java 8 Maven plugin + * and build daemon, and the Java 17 Settings tool — and because a + * catalog that javac itself checks is the same argument the annotation feature + * rests on.

+ * + *

Keep this file in sync with the BuildDaemon copy. Like + * {@link PlatformFeatureCatalog}, this class is mirrored into the out-of-repo + * build service; a single {@code .java} file is the sync unit.

+ * + *

Registration is split into one method per group rather than a single + * static block on purpose: a class initializer carrying every entry would + * exceed the JVM's 64KB per-method bytecode limit.

+ */ +public final class BuildHints { + + /** Prefix every build hint carries inside a settings or library properties file. */ + public static final String ARG_PREFIX = "codename1.arg."; + + private static final List ENTRIES; + private static final Map BY_NAME; + + static { + List h = new ArrayList(); + BuildHintsIos.register(h); + BuildHintsAndroid.register(h); + BuildHintsApple.register(h); + BuildHintsDesktop.register(h); + BuildHintsGeneral.register(h); + BuildHintsDynamic.register(h); + BuildHintsExternal.register(h); + + Map byName = new LinkedHashMap(); + for (Hint entry : h) { + if (byName.put(entry.name(), entry) != null) { + throw new IllegalStateException("Duplicate build hint: " + entry.name()); + } + } + ENTRIES = Collections.unmodifiableList(h); + BY_NAME = Collections.unmodifiableMap(byName); + } + + private BuildHints() { + } + + /** Every catalogued hint, in registration order. */ + public static List entries() { + return ENTRIES; + } + + /** + * Looks up a hint by its bare name. + * + * @param name the hint name, with or without the {@link #ARG_PREFIX} + * @return the hint, or null when the catalog does not describe it + */ + public static Hint byName(String name) { + if (name == null) { + return null; + } + return BY_NAME.get(strip(name)); + } + + /** Removes the {@link #ARG_PREFIX} if present. */ + public static String strip(String name) { + if (name != null && name.startsWith(ARG_PREFIX)) { + return name.substring(ARG_PREFIX.length()); + } + return name; + } + + /** + * The string that joins two values of this hint when a cn1lib appends to a + * project's value, and that splits an annotation's {@code String[]} back + * into wire form. + * + *

Returns the empty string for a hint the catalog does not describe, + * which is the historical bare-concatenation behaviour that the XML + * fragment hints depend on.

+ */ + public static String separatorFor(String name) { + Hint entry = byName(name); + if (entry == null || entry.separator() == null) { + return ""; + } + return entry.separator(); + } + + /** + * Resolves an alias to the hint whose value it overrides. A few Android + * hints have a short {@code and.} spelling that takes precedence over the + * {@code android.} one; both names denote a single effective setting, so + * conflict detection has to collapse them. + * + * @return the aliased hint, or the argument itself when it is not an alias + */ + public static Hint resolve(Hint entry) { + if (entry == null || entry.aliasOf() == null) { + return entry; + } + Hint target = byName(entry.aliasOf()); + return target == null ? entry : target; + } + + /** The hint a name ultimately denotes, following an alias if there is one. */ + public static String canonicalName(String name) { + Hint entry = byName(name); + if (entry == null) { + return strip(name); + } + return resolve(entry).name(); + } + + /** + * The type vocabulary the Settings tool searches and validates by. Derived + * so it can no longer drift from {@link HintType}. + * + * @return one of BOOLEAN, INTEGER, VERSION, ENUM, XML, PATH, URL, CSV, + * SECRET, TEXT + */ + public static String settingsType(HintType type) { + switch (type) { + case BOOLEAN: return "BOOLEAN"; + case INT: return "INTEGER"; + case VERSION: return "VERSION"; + case ENUM: return "ENUM"; + case XML: return "XML"; + case PATH: return "PATH"; + case URL: return "URL"; + case STRING_LIST: return "CSV"; + case SECRET: return "SECRET"; + default: return "TEXT"; + } + } + + /** + * The widget the simulator's Build Hint editor renders. Derived so it can + * no longer drift from {@link HintType}. + * + * @return one of TextField, TextArea, Checkbox, Select + */ + public static String editorWidget(HintType type) { + switch (type) { + case BOOLEAN: return "Checkbox"; + case ENUM: return "Select"; + case TEXT_BLOCK: + case STRING_LIST: + case XML: return "TextArea"; + default: return "TextField"; + } + } + + /** + * One build hint. + * + *

Built fluently. Only {@link #name} is required; everything else + * defaults to "plain string, no default, not annotated", which is the + * correct shallow description of a hint nobody has curated yet.

+ */ + public static final class Hint { + private final String name; + private String aliasOf; + private String deprecated; + private HintGroup group = HintGroup.NONE; + private String attr; + private HintType type = HintType.STRING; + private String enumName; + private final List values = new ArrayList(); + private final List valueLabels = new ArrayList(); + private String def; + private String separator; + private String platform = "general"; + private boolean dynamic; + private String pattern; + private final List consumedBy = new ArrayList(); + private boolean external; + private boolean enterpriseOnly; + private String link; + private String doc = ""; + + Hint(String name) { + if (name == null || name.length() == 0) { + throw new IllegalArgumentException("Build hint name is required"); + } + this.name = name; + } + + /** Marks this hint as an override alias of another. */ + public Hint aliasOf(String other) { + this.aliasOf = other; + return this; + } + + /** Records that this hint is deprecated, naming what replaces it. */ + public Hint deprecated(String reason) { + this.deprecated = reason; + return this; + } + + /** Assigns the annotation type and the attribute name it is exposed as. */ + public Hint annotatedAs(HintGroup g, String attribute) { + this.group = g; + this.attr = attribute; + return this; + } + + /** Sets the group without exposing the hint as an annotation attribute. */ + public Hint group(HintGroup g) { + this.group = g; + return this; + } + + public Hint type(HintType t) { + this.type = t; + return this; + } + + /** + * Declares a closed value domain. Values are in wire form, i.e. + * exactly what the builder compares against, never the enum constant + * name. + */ + public Hint values(String enumTypeName, String... wireValues) { + this.type = HintType.ENUM; + this.enumName = enumTypeName; + this.values.clear(); + for (String v : wireValues) { + if (v.indexOf(',') >= 0) { + throw new IllegalArgumentException( + "Build hint " + name + " value '" + v + "' contains a comma, which the " + + "simulator's Build Hint editor uses to delimit its value list"); + } + this.values.add(v); + } + return this; + } + + /** Optional human labels for the value domain, parallel to the values. */ + public Hint valueLabels(String... labels) { + this.valueLabels.clear(); + Collections.addAll(this.valueLabels, labels); + return this; + } + + /** + * The builder's own default, i.e. the second argument of the + * {@code getArg} call that reads this hint. + */ + public Hint def(String value) { + this.def = value; + return this; + } + + /** + * The string that joins appended values. Empty string means the values + * abut directly, which is what the XML-fragment hints want. + */ + public Hint separator(String sep) { + this.separator = sep; + return this; + } + + public Hint platform(String p) { + this.platform = p; + return this; + } + + /** Declares an open-ended family of hints matching a name pattern. */ + public Hint dynamic(String namePattern) { + this.dynamic = true; + this.pattern = namePattern; + return this; + } + + /** Names the builders or mojos that read this hint. */ + public Hint consumedBy(String... classSimpleNames) { + Collections.addAll(this.consumedBy, classSimpleNames); + return this; + } + + /** + * Marks a hint that is read outside this repository, by a build-daemon + * lane whose source is not mirrored here. Such a hint has no in-repo + * consumer and that is not evidence it is dead. + */ + public Hint external() { + this.external = true; + return this; + } + + public Hint enterpriseOnly() { + this.enterpriseOnly = true; + return this; + } + + public Hint link(String url) { + this.link = url; + return this; + } + + /** One paragraph, reused verbatim by the docs, the javadoc and the UI. */ + public Hint doc(String text) { + this.doc = text == null ? "" : text; + return this; + } + + public String name() { return name; } + public String aliasOf() { return aliasOf; } + public String deprecated() { return deprecated; } + public HintGroup group() { return group; } + public String attr() { return attr; } + public HintType type() { return type; } + public String enumName() { return enumName; } + public List values() { return Collections.unmodifiableList(values); } + public List valueLabels() { return Collections.unmodifiableList(valueLabels); } + public String def() { return def; } + public String separator() { return separator; } + public String platform() { return platform; } + public boolean isDynamic() { return dynamic; } + public String pattern() { return pattern; } + public List consumedBy() { return Collections.unmodifiableList(consumedBy); } + public boolean isExternal() { return external; } + public boolean isEnterpriseOnly() { return enterpriseOnly; } + public String link() { return link; } + public String doc() { return doc; } + + /** Whether this hint is exposed as an annotation attribute. */ + public boolean isAnnotated() { + return attr != null && group.isAnnotated(); + } + + /** The full settings-file key, including the {@link #ARG_PREFIX}. */ + public String propertyKey() { + return ARG_PREFIX + name; + } + + @Override + public String toString() { + return name; + } + } +} diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java new file mode 100644 index 00000000000..240be102a79 --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java @@ -0,0 +1,1445 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +import com.codename1.build.shared.BuildHints.Hint; + +import java.util.List; + +/** + * Android build hints, including the {@code and.} override aliases. + * + *

Seeded by mining every {@code getArg} call site in the builders, so the + * name and the default match what the build actually reads. Curated entries + * carry an annotation attribute and, where the domain is provably closed, an + * enum; the rest are described but set through + * {@code codenameone_settings.properties}.

+ * + *

Split out of {@link BuildHints} because a single class initializer + * holding every entry would exceed the JVM's 64KB per-method limit.

+ */ +final class BuildHintsAndroid { + + private BuildHintsAndroid() { + } + + static void register(List h) { + h.add(new Hint("and.captureRecord") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("and.facebook_permissions") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder", "IPhoneBuilder")); + + h.add(new Hint("and.themeMode") + .annotatedAs(HintGroup.ANDROID, "themeMode") + .values("AndroidThemeMode", "auto", "modern", "hololight", "legacy") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("`auto`, `modern` / `material`, `hololight` (default for existing apps), `legacy`. `auto` " + + "and `modern` / `material` opt in to the CSS-generated Android Material 3 theme from " + + "`native-themes/android-material/theme.css`. `hololight` is Android Holo Light (what the " + + "framework shipped on API 14+ before this refactor). `legacy` loads the pre-Holo Android " + + "theme. The legacy alias `cn1.androidTheme` is still accepted, and `and.hololight=true` " + + "still maps to `hololight`. The default stays on `hololight` for existing apps until you " + + "flip in a future release.")); + + h.add(new Hint("android.NotificationChannel.description") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("Remote notifications") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.NotificationChannel.enableLights") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.NotificationChannel.enableVibration") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.NotificationChannel.id") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("cn1-channel") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.NotificationChannel.importance") + .group(HintGroup.ANDROID) + .type(HintType.INT) + .def("2") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.NotificationChannel.lightColor") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.NotificationChannel.name") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("Notifications") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.NotificationChannel.vibrationPattern") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.accessibilityGuard") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.accessibilityGuard.allow") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.accessibilityGuard.mode") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("exit") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.activity.launchMode") + .annotatedAs(HintGroup.ANDROID, "activityLaunchMode") + .type(HintType.STRING) + .def("singleTop") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Allows explicitly setting the `android:launchMode` attribute of the main activity in " + + "android. Default is \"singleTop,\" but for some applications you may need to change this " + + "behaviour. In particular, apps that are meant to open a file type will need to set this " + + "to \"singleTask.\" See " + + "https://developer.android.com/guide/topics/manifest/activity-element.html[Android docs " + + "for the activity element] for more information about the `android:launchMode` attribute.")); + + h.add(new Hint("android.activityClassBody") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.activityClassImports") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.adaptiveIconBackground") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("#ffffff") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Background color to use for adaptive icons when `android.enableAdaptiveIcons=true` and " + + "no background image is supplied. Defaults to `#ffffff` and is written as " + + "`@color/ic_launcher_background`.")); + + h.add(new Hint("android.adaptiveIconBackgroundImage") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Optional path (relative to the root of the native Android project) to an image file to " + + "use as the adaptive icon background when `android.enableAdaptiveIcons=true`. If this " + + "property is set, it overrides `android.adaptiveIconBackground`.")); + + h.add(new Hint("android.allowBackup") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.androidAuto.messaging") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.androidAuto.minCarApiLevel") + .group(HintGroup.ANDROID) + .type(HintType.INT) + .def("1") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.androidAuto.navigation") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.androidAuto.poi") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.anyDensity") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.apacheLegacy") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.appBundle") + .annotatedAs(HintGroup.ANDROID, "appBundle") + .type(HintType.BOOLEAN) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Produces an Android App Bundle (.aab) rather than an APK. Required for new Play Store " + + "submissions.")); + + h.add(new Hint("android.appReview.version") + .group(HintGroup.ANDROID) + .type(HintType.VERSION) + .def("2.0.1") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.ar.required") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.arrcompile") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.arrimplementation") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.asyncPaint") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to true. Toggles the Android pipeline between the legacy " + + "pipeline (false) and new pipeline (true)")); + + h.add(new Hint("android.background_push_handling") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.billingclient.version") + .group(HintGroup.ANDROID) + .type(HintType.VERSION) + .def("4.0.0") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.blockExternalStoragePermission") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to false. Disables the external storage (SD card) permission")); + + h.add(new Hint("android.blockReadMediaPermissions") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false, defaults to the value of `android.blockExternalStoragePermission`. " + + "Suppresses the `READ_MEDIA_VIDEO` and `READ_MEDIA_AUDIO` permissions that playing a URI " + + "adds on API 33 and above")); + + h.add(new Hint("android.bluetooth.neverForLocation") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.bluetooth.required") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.buildToolsVersion") + .annotatedAs(HintGroup.ANDROID, "buildToolsVersion") + .type(HintType.VERSION) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Android build-tools version. It also selects the compile SDK, so there is no separate " + + "compile-SDK hint.")); + + h.add(new Hint("android.captureRecord") + .annotatedAs(HintGroup.ANDROID, "captureRecord") + .type(HintType.STRING) + .def("enabled") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Indicates whether the `RECORD_AUDIO` permission should be requested. Can be `enabled` or " + + "any other value to disable this option")); + + h.add(new Hint("android.carAppVersion") + .group(HintGroup.ANDROID) + .type(HintType.VERSION) + .def("1.4.0") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.credentialsPlayServicesVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.credentialsVersion") + .group(HintGroup.ANDROID) + .type(HintType.VERSION) + .def("1.3.0") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.cusom_layout") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.cusom_layout1") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Applies to any number of layouts as long as they're in sequence (for example, " + + "android.cusom_layout2, android.cusom_layout3 etc.). Will write the content of the " + + "argument as a layout XML file and give it the name `cusom_layout1.xml` onwards. This can " + + "be used by native code to work with XML files")); + + h.add(new Hint("android.customActivity") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("CodenameOneActivity") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.customTabsVersion") + .group(HintGroup.ANDROID) + .type(HintType.VERSION) + .def("1.8.0") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.debug") + .annotatedAs(HintGroup.ANDROID, "debug") + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("true/false defaults to true - indicates whether to include the debug version in the " + + "build. Defaults conditionally rather than to a fixed value: when android.release is on " + + "it defaults to false, and when release is off it defaults to true, so a build that " + + "selects neither still produces something installable " + + "(AndroidGradleBuilder.java:447-451).")); + + h.add(new Hint("android.decouplePlayServiceVersions") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.delayPushCompletion") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.disableR8") + .annotatedAs(HintGroup.ANDROID, "disableR8") + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Turns off R8, falling back to the older shrinker. Note that hardening requires R8, so " + + "this conflicts with harden.level.")); + + h.add(new Hint("android.disableR8FullMode") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.disableScreenshots") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.enableAdaptiveIcons") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder", "CN1BuildMojo") + .doc("Boolean true/false defaults to false. Enables Android adaptive icon generation in " + + "Android Gradle builds. When enabled, Codename One generates `mipmap` launcher resources " + + "(`ic_launcher`, `ic_launcher_foreground`, and adaptive XML in `mipmap-anydpi-v26`) and " + + "uses them in the application manifest (`android:icon` and `android:roundIcon`).")); + + h.add(new Hint("android.enableProguard") + .annotatedAs(HintGroup.ANDROID, "enableProguard") + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to true. Allows disabling the proguard obfuscation even on " + + "release builds, notice that this isn't recommended")); + + h.add(new Hint("android.excludeBolts") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.extendAppCompatActivity") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.facebookSdkVersion") + .group(HintGroup.ANDROID) + .type(HintType.VERSION) + .def("16.2.0") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.facebook_permissions") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("\\\"public_profile\\\",\\\"email\\\",\\\"user_friends\\\"") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Permissions for Facebook used in the Android build target, applicable only if Facebook " + + "native integration is used.")); + + h.add(new Hint("android.file_paths") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def(" ") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.firebaseAnalytics") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.firebaseAnalyticsVersion") + .group(HintGroup.ANDROID) + .type(HintType.VERSION) + .def("21.5.0") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.firebaseCoreVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.firebaseMessagingVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.foldableSupport") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.forceJava8Builder") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.foregroundServiceType") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("dataSync") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.fridaDetection") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to false. Indicates whether the app should check for the " + + "presence of the https://www.frida.re/[Frida] dynamic instrumentation toolkit on the " + + "device. If Frida is detected, the app will exit. This uses the " + + "[frida-blocker](https://github.com/shannah/frida-blocker) library to perform the frida " + + "detection.")); + + h.add(new Hint("android.fullScreenIntent") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.googleAdUnitId") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Allows integrating admob/google play ads, this is effectively identical to " + + "google.adUnitId but only applies to Android")); + + h.add(new Hint("android.googleAdUnitTestDevice") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("C6783E2486F0931D9D09FABC65094FDF") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Device key used to mark a specific Android device as a test device for Google Play ads " + + "defaults to C6783E2486F0931D9D09FABC65094FDF")); + + h.add(new Hint("android.gpsPermission") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Indicates whether the GPS permission should be requested, it's autodetected by default " + + "if you use the location API. But, some code might want to explicitly define it")); + + h.add(new Hint("android.gradle.androidx") + .group(HintGroup.ANDROID) + .type(HintType.STRING_LIST) + .separator("\n") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.gradleDep") + .annotatedAs(HintGroup.ANDROID, "gradleDep") + .type(HintType.STRING_LIST) + .separator(";") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Gradle dependency statements to add to the app module, such as implementation " + + "'com.example:lib:1.0'.")); + + h.add(new Hint("android.gradlePlugin") + .group(HintGroup.ANDROID) + .type(HintType.STRING_LIST) + .separator("\n") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.hce") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.hceAids") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("F0010203040506") + .platform("android") + .consumedBy("AndroidGradleBuilder", "IPhoneBuilder")); + + h.add(new Hint("android.hceCategory") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("other") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.hceDescription") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.hceRequireUnlock") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.headphoneCallback") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to false. When set to true it assumes the main class has two " + + "methods: `headphonesConnected` & `headphonesDisconnected` which it invokes appropriately " + + "as needed")); + + h.add(new Hint("android.health.background") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.health.connectVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("1.1.0-alpha07") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.health.history") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.health.privacyPolicyUrl") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.health.read") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.health.write") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.hideOverlayWindows") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to false. Declares the " + + "`android.permission.HIDE_OVERLAY_WINDOWS` permission needed by " + + "`DeviceIntegrity.setHideOverlayWindows()` on Android 12+, for apps that call the runtime " + + "API without enabling `android.tapjackingGuard`. A normal install-time permission, so the " + + "user sees no prompt.")); + + h.add(new Hint("android.hideStatusBar") + .annotatedAs(HintGroup.ANDROID, "hideStatusBar") + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Hides the Android status bar.")); + + h.add(new Hint("android.hms.pushVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("6.3.0.302") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.home.playServicesVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("16.0.0-beta1") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.includeGPlayServices") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("*Deprecated, please android.playService.+++*+++!* Indicates whether Google Play Services " + + "should be included into the build, defaults to false but that might change based on the " + + "functionality of the application and other build hints. Adding Google Play Services " + + "support allows you to use a more refined location implementation and invoke some Google " + + "specific functionality from native code.")); + + h.add(new Hint("android.includeMavenCentral") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.installLocation") + .annotatedAs(HintGroup.ANDROID, "installLocation") + .values("InstallLocation", "auto", "internalOnly", "preferExternal") + .def("auto") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Maps to android:installLocation manifest entry defaults to auto. Can also be set to " + + "internalOnly or preferExternal.")); + + h.add(new Hint("android.java8") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.keyboardOpen") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to true. Toggles the new async keyboard mode that leaves the " + + "keyboard open while you move between text components")); + + h.add(new Hint("android.largeScreens") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.licenseKey") + .annotatedAs(HintGroup.ANDROID, "licenseKey") + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("The license key for the Android app, this is required if you use in-app purchase on " + + "Android")); + + h.add(new Hint("android.locales") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.manifest.queries") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Embeds XML content into the section of the Android manifest file. This is " + + "https://developer.android.com/training/package-visibility[required in Android 11 for " + + "package visibility]. See " + + "https://developer.android.com/guide/topics/manifest/queries-element[queries element " + + "Android documentation].")); + + h.add(new Hint("android.messagingService") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.migrateToAndroidX") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.min_sdk_version") + .annotatedAs(HintGroup.ANDROID, "minSdkVersion") + .type(HintType.INT) + .def("19") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("The least SDK required to run this app, the default value changes based on functionality " + + "but can be as low as 7. This corresponds to the XML attribute `android:minSdkVersion`.")); + + h.add(new Hint("android.mockLocation") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to true. Toggles the mock location permission which is on by " + + "default, this allows easier debugging of Android device location based services")); + + h.add(new Hint("android.mopubId") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.multidex") + .annotatedAs(HintGroup.ANDROID, "multidex") + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to false. Multidex allows Android binaries to reference more " + + "than 65536 methods. This slows builds a bit so you have it off by default but if you get " + + "a build error mentioning this limit you should turn this on.")); + + h.add(new Hint("android.newFirebaseMessaging") + .annotatedAs(HintGroup.ANDROID, "newFirebaseMessaging") + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Uses the current Firebase Cloud Messaging integration. Requires AndroidX and Gradle 8.13 " + + "or newer.")); + + h.add(new Hint("android.nonconsumable") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Comma delimited string of items that are non-consumable in the in-app purchase API")); + + h.add(new Hint("android.normalScreens") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.onCreate") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playIntegrity") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playIntegrity.verifyUrl") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playIntegrityVersion") + .group(HintGroup.ANDROID) + .type(HintType.VERSION) + .def("1.4.0") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.ads") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.analytics") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.appInvite") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.auth") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.base") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.cast") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.drive") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.fitness") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.games") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.gcm") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.identity") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.indexing") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.location") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.maps") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.nearby") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.panorama") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.plus") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.safetynet") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.vision") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.wallet") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playService.wearable") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.playServicesVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("The version number of play services to build against. Experimental. **Use with caution** " + + "as building against versions other than the server default may introduce " + + "incompatibilities with some Codename One APIs.")); + + h.add(new Hint("android.proguardKeep") + .annotatedAs(HintGroup.ANDROID, "proguardKeep") + .type(HintType.STRING_LIST) + .separator("\n") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Arguments for the keep option in proguard allowing you to keep a pattern of files for " + + "example, `-keep class com.mypackage.ProblemClass { *; }`")); + + h.add(new Hint("android.proguardKeepOverride") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("Exceptions, InnerClasses, Signature, Deprecated, SourceFile, LineNumberTable, *Annotation*, EnclosingMethod") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.pushSound") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.pushVibratePattern") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Comma delimited long values to describe the push pattern of vibrate used for the " + + "`setVibrate` native method")); + + h.add(new Hint("android.release") + .annotatedAs(HintGroup.ANDROID, "release") + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("true/false defaults to true - indicates whether to include the release version in the " + + "build")); + + h.add(new Hint("android.removeBasePermissions") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to false. Disables the built-in permissions specifically " + + "`INTERNET` permission (that is, no networking...)")); + + h.add(new Hint("android.repositories") + .annotatedAs(HintGroup.ANDROID, "repositories") + .type(HintType.STRING_LIST) + .separator("\n") + .platform("android") + .consumedBy("AndroidGradleBuilder", "MapsProviderInjector") + .doc("Extra Gradle repositories to resolve dependencies from.")); + + h.add(new Hint("android.requestReadMediaPermissions") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to false. Declares `READ_MEDIA_IMAGES`, `READ_MEDIA_VIDEO` " + + "and `READ_MEDIA_AUDIO` on API 33 and above even when the build detected no media " + + "playback. `READ_MEDIA_IMAGES` is only ever added by this hint")); + + h.add(new Hint("android.rootCheck") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to false. Indicates whether the app should check for root " + + "access on the device. If root access is detected, the app will exit.")); + + h.add(new Hint("android.rootbeerVersion") + .group(HintGroup.ANDROID) + .type(HintType.VERSION) + .def("0.1.0") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.shareFilter") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.sharedUserId") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Allows adding a manifest attribute for the sharedUserId option")); + + h.add(new Hint("android.sharedUserLabel") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Allows adding a manifest attribute for the sharedUserLabel option")); + + h.add(new Hint("android.shrinkResources") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to false. Used only in conjunction with " + + "android.enableProguard. Strips out unused resources to reduce apk size. Since 7.0")); + + h.add(new Hint("android.smallScreens") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to true. Corresponds to the `android:smallScreens` XML " + + "attribute and allows disabling the support for small phones")); + + h.add(new Hint("android.stack_size") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Size in bytes for the Android stack thread")); + + h.add(new Hint("android.statusbar_hidden") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("true/false defaults to false. When set to true hides the status bar on Android devices.")); + + h.add(new Hint("android.store_ids") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.streamMode") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("The mode in which the volume key should behave, defaults to OS default. Allows setting " + + "it to `music` for music playback apps")); + + h.add(new Hint("android.stringsXml") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Allows injecting more entries into the strings.xml file using a value that includes " + + "something like this `value1value2`")); + + h.add(new Hint("android.style") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Allows injecting more data into the `styles.xml` file right before the closing resources " + + "tag")); + + h.add(new Hint("android.supportScreens") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.supportv4Dep") + .group(HintGroup.ANDROID) + .type(HintType.STRING_LIST) + .separator("\n") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.surfaces.exactAlarms") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.tapjackingGuard") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to false. Switches on tapjacking / screen-overlay protection " + + "at launch, so touches that arrive while another app's window covers this one are " + + "detected and dropped. See the security chapter.")); + + h.add(new Hint("android.tapjackingGuard.hideOverlays") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to true. Also asks Android 12+ to hide overlay windows drawn " + + "over the app, which is the only mitigation that covers native peer components, and " + + "declares the `HIDE_OVERLAY_WINDOWS` permission it requires. Only relevant if " + + "`android.tapjackingGuard=true`.")); + + h.add(new Hint("android.tapjackingGuard.mode") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("block") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("`block` (default), `strict`, `report` or `off`. `block` drops gestures that start on a " + + "fully obscured window, `report` only observes, `strict` also drops touches where only " + + "part of the window is covered (which benign system UI can trigger). Only relevant if " + + "`android.tapjackingGuard=true`.")); + + h.add(new Hint("android.targetSDKVersion") + .annotatedAs(HintGroup.ANDROID, "targetSDKVersion") + .type(HintType.INT) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Indicates the Android SDK used to compile the Android build defaults to 21. Notice that " + + "not all targets will work since the source might have some limitations and not all SDK " + + "targets are installed on the build servers.")); + + h.add(new Hint("android.textureView") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.theme") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("Light") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Light or Dark defaults to Light. On Android 4+ the default Holo theme is used to render " + + "the native widgets sometimes and this indicates whether holo light or holo dark is used. " + + "This doesn't affect the Codename One theme but that might change in the future.")); + + h.add(new Hint("android.topDependency") + .annotatedAs(HintGroup.ANDROID, "topDependency") + .type(HintType.STRING_LIST) + .separator("\n") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Statements added to the top-level Gradle build file rather than the app module.")); + + h.add(new Hint("android.tv") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("true/false (defaults to false). Marks the build as an Android TV / Google TV app. Adds " + + "the `LEANBACK_LAUNCHER` intent category to the launcher activity (so the app appears on " + + "the TV home screen), declares the `android.software.leanback` feature, makes " + + "`android.hardware.touchscreen` optional (so it installs on touchless TVs), and generates " + + "a 320×180 launcher banner (`@drawable/tv_banner`) from the app icon. The same APK still " + + "installs and runs on phones and tablets, and `CN.isTV()` returns true at runtime on a " + + "TV.")); + + h.add(new Hint("android.useAndroidX") + .annotatedAs(HintGroup.ANDROID, "useAndroidX") + .type(HintType.BOOLEAN) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Use Android X instead of support libraries. This will also run a find/replace on all " + + "source files to replace support libraries and artifacts with AndroidX equivalents.")); + + h.add(new Hint("android.useGradle8") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.versionCode") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Allows overriding the auto generated version number with a custom internal version " + + "number specifically used for the XML attribute `android:versionCode`")); + + h.add(new Hint("android.wear") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.wear.standalone") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.web_loading_hidden") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("true/false defaults to false - set to true to hide the progress indicator that appears " + + "when loading a web page on Android.")); + + h.add(new Hint("android.windowVersion") + .group(HintGroup.ANDROID) + .type(HintType.VERSION) + .def("1.3.0") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.xactivity") + .group(HintGroup.ANDROID) + .type(HintType.XML) + .separator("") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Allows injecting more attributes into the `activity` tag in the Android XML")); + + h.add(new Hint("android.xapplication") + .annotatedAs(HintGroup.ANDROID, "xapplication") + .type(HintType.XML) + .separator("") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("defaults to an empty string. Allows developers of native Android code to add text within " + + "the application block to define things such as widgets, services etc.")); + + h.add(new Hint("android.xapplication_attr") + .group(HintGroup.ANDROID) + .type(HintType.XML) + .separator(" ") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Allows injecting more attributes into the `application`` tag in the Android XML")); + + h.add(new Hint("android.xgradle") + .annotatedAs(HintGroup.ANDROID, "xgradle") + .type(HintType.STRING_LIST) + .separator("\n") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Arbitrary text spliced into the generated app-module Gradle file.")); + + h.add(new Hint("android.xgradle_default_config") + .group(HintGroup.ANDROID) + .type(HintType.STRING_LIST) + .separator("\n") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.xintent_filter") + .group(HintGroup.ANDROID) + .type(HintType.XML) + .separator("") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Allows adding an intent filter to the main android activity")); + + h.add(new Hint("android.xlargeScreens") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.xlayout_attr") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.xmanifest") + .group(HintGroup.ANDROID) + .type(HintType.XML) + .separator("") + .platform("android") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.xpermissions") + .annotatedAs(HintGroup.ANDROID, "xpermissions") + .type(HintType.XML) + .separator("") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("more permissions for the Android manifest")); + } +} diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java new file mode 100644 index 00000000000..d606f485d0a --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +import com.codename1.build.shared.BuildHints.Hint; + +import java.util.List; + +/** + * macOS Catalyst, tvOS and watchOS native-slice build hints. + * + *

Seeded by mining every {@code getArg} call site in the builders, so the + * name and the default match what the build actually reads. Curated entries + * carry an annotation attribute and, where the domain is provably closed, an + * enum; the rest are described but set through + * {@code codenameone_settings.properties}.

+ * + *

Split out of {@link BuildHints} because a single class initializer + * holding every entry would exceed the JVM's 64KB per-method limit.

+ */ +final class BuildHintsApple { + + private BuildHintsApple() { + } + + static void register(List h) { + h.add(new Hint("macNative.appCategory") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .def("public.app-category.utilities") + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. `LSApplicationCategoryType` in the generated Info.plist. Default " + + "`public.app-category.utilities`. See " + + "https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype[Apple's " + + "category list].")); + + h.add(new Hint("macNative.bundleId") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. Used only when `macNative.deriveBundleId=false`. Default: " + + "`.mac`.")); + + h.add(new Hint("macNative.copyright") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. `NSHumanReadableCopyright` in the Info.plist. Defaults to " + + "`Copyright (c) `.")); + + h.add(new Hint("macNative.deriveBundleId") + .group(HintGroup.MAC_NATIVE) + .type(HintType.BOOLEAN) + .def("true") + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. `true` (default) maps to Xcode's " + + "`DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER=YES` (Xcode appends `.maccatalyst` to the " + + "iOS bundle ID). Set to `false` to take the bundle ID verbatim from `macNative.bundleId`.")); + + h.add(new Hint("macNative.distribution") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .def("appStore") + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. `appStore` (default), `developerID`, or `both`. Selects which " + + "entitlements + ExportOptions plist + signing certificate to emit. `both` emits parallel " + + "`*-AppStore.entitlements` / `*-DeveloperID.entitlements` and matching " + + "`ExportOptions-*-Mac.plist` files so a single project can be archived to either channel.")); + + h.add(new Hint("macNative.enabled") + .group(HintGroup.MAC_NATIVE) + .type(HintType.BOOLEAN) + .def("false") + .platform("mac") + .consumedBy("CN1BuildMojo", "IPhoneBuilder", "MacNativeBuilder")); + + h.add(new Hint("macNative.entitlements.extra") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. Free-form XML inserted verbatim inside the `…` of " + + "the generated entitlements plist. Use for entitlements Codename One doesn't expose " + + "individually.")); + + h.add(new Hint("macNative.entitlements.files.userSelected") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .def("readwrite") + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. `readwrite` (default), `readonly`, or `none`. Sets the matching " + + "`com.apple.security.files.user-selected.*` entitlement.")); + + h.add(new Hint("macNative.fixedWindowSize") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. Opt-in. Format `x` — for example `1024x685`. When " + + "set, the Catalyst window's `UISceneSession.sizeRestrictions` minimum and maximum are " + + "pinned to the requested size so every launch produces a byte-identical window. Default " + + "unset, in which case the window is resizable. The CI screenshot pipeline turns this on " + + "to keep the strict-pixel golden comparison stable; production apps should leave it off.")); + + h.add(new Hint("macNative.iosMinDeploymentTarget") + .group(HintGroup.MAC_NATIVE) + .type(HintType.VERSION) + .def("13.1") + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. iOS deployment-target floor for the Catalyst slice " + + "(`IPHONEOS_DEPLOYMENT_TARGET`). Default `13.1`. The plugin coerces the iOS slice's " + + "minimum upward when set.")); + + h.add(new Hint("macNative.minDeploymentTarget") + .group(HintGroup.MAC_NATIVE) + .type(HintType.VERSION) + .def("10.15") + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. Minimum macOS version (`MACOSX_DEPLOYMENT_TARGET`). Default " + + "`10.15` — earlier versions don't support Mac Catalyst.")); + + h.add(new Hint("macNative.notarize") + .group(HintGroup.MAC_NATIVE) + .type(HintType.BOOLEAN) + .def("false") + .platform("mac") + .consumedBy("MacNativeBuilder")); + + h.add(new Hint("macNative.notarize.appleId") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .consumedBy("MacNativeBuilder")); + + h.add(new Hint("macNative.notarize.keychainProfile") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .consumedBy("MacNativeBuilder")); + + h.add(new Hint("macNative.notarize.password") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .consumedBy("MacNativeBuilder")); + + h.add(new Hint("macNative.notarize.teamId") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .consumedBy("MacNativeBuilder")); + + h.add(new Hint("macNative.signing.style") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .def("automatic") + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. `automatic` (default) lets Xcode pick the signing certificate; " + + "`manual` forces the certificate identity hints below to be respected verbatim.")); + + h.add(new Hint("macNative.signingIdentity.appStore") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .def("Apple Distribution") + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. Signing certificate identity for the App Store channel. Default " + + "`Apple Distribution`.")); + + h.add(new Hint("macNative.signingIdentity.developerID") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .def("Developer ID Application") + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. Signing certificate identity for the Developer ID channel. " + + "Default `Developer ID Application`.")); + + h.add(new Hint("macNative.teamId") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .consumedBy("MacNativeBuilder") + .doc("Mac Native builds only. Apple Developer Team ID (alphanumeric). Falls back to " + + "`ios.release.teamId` → `ios.teamId` → `ios.debug.teamId` since most apps share a single " + + "Apple Developer Team for iOS and Mac.")); + + h.add(new Hint("tvNative.bundleId") + .group(HintGroup.TV_NATIVE) + .type(HintType.STRING) + .platform("tv") + .consumedBy("TvNativeBuilder") + .doc("Bundle identifier of the tvOS app. Defaults to `.tvos`.")); + + h.add(new Hint("tvNative.displayName") + .group(HintGroup.TV_NATIVE) + .type(HintType.STRING) + .platform("tv") + .consumedBy("TvNativeBuilder") + .doc("The tvOS app name shown on Apple TV. Defaults to the app's display name.")); + + h.add(new Hint("tvNative.enabled") + .group(HintGroup.TV_NATIVE) + .type(HintType.BOOLEAN) + .def("false") + .platform("tv") + .consumedBy("IPhoneBuilder", "TvNativeBuilder") + .doc("true/false (defaults to false). Adds an Apple TV (tvOS) application target to the iOS " + + "build. The tvOS app is a separate `appletvos` target built from the same Java/Kotlin " + + "sources through ParparVM (UIKit + Metal; tvOS has no OpenGL ES). Enabling it doesn't " + + "change the iOS app -- in particular it doesn't override the iOS app's `ios.metal` " + + "setting. Also turned on implicitly by `codename1.tvMain`.")); + + h.add(new Hint("tvNative.mainClass") + .group(HintGroup.TV_NATIVE) + .type(HintType.STRING) + .platform("tv") + .consumedBy("IPhoneBuilder", "TvNativeBuilder")); + + h.add(new Hint("tvNative.minDeploymentTarget") + .group(HintGroup.TV_NATIVE) + .type(HintType.VERSION) + .def("13.0") + .platform("tv") + .consumedBy("TvNativeBuilder") + .doc("`TVOS_DEPLOYMENT_TARGET` for the tvOS target. Defaults to `13.0`.")); + + h.add(new Hint("tvNative.teamId") + .group(HintGroup.TV_NATIVE) + .type(HintType.STRING) + .platform("tv") + .consumedBy("TvNativeBuilder") + .doc("Apple Developer Team ID used to sign the tvOS target. Falls back to the iOS team id " + + "(`ios.release.teamId` / `ios.teamId` / `ios.debug.teamId`).")); + + h.add(new Hint("watchNative.enabled") + .group(HintGroup.WATCH_NATIVE) + .type(HintType.BOOLEAN) + .def("false") + .platform("watch") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("watchNative.health") + .group(HintGroup.WATCH_NATIVE) + .type(HintType.STRING) + .platform("watch") + .consumedBy("WatchNativeBuilder")); + + h.add(new Hint("watchNative.health.workoutProcessing") + .group(HintGroup.WATCH_NATIVE) + .type(HintType.BOOLEAN) + .def("false") + .platform("watch") + .consumedBy("WatchNativeBuilder")); + + h.add(new Hint("watchNative.mainClass") + .group(HintGroup.WATCH_NATIVE) + .type(HintType.STRING) + .platform("watch") + .consumedBy("IPhoneBuilder")); + } +} diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java new file mode 100644 index 00000000000..aee3bf9532d --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +import com.codename1.build.shared.BuildHints.Hint; + +import java.util.List; + +/** + * Desktop, native Windows, native Linux and JavaScript build hints. + * + *

Seeded by mining every {@code getArg} call site in the builders, so the + * name and the default match what the build actually reads. Curated entries + * carry an annotation attribute and, where the domain is provably closed, an + * enum; the rest are described but set through + * {@code codenameone_settings.properties}.

+ * + *

Split out of {@link BuildHints} because a single class initializer + * holding every entry would exceed the JVM's 64KB per-method limit.

+ */ +final class BuildHintsDesktop { + + private BuildHintsDesktop() { + } + + static void register(List h) { + h.add(new Hint("desktop.adaptToRetina") + .annotatedAs(HintGroup.DESKTOP, "adaptToRetina") + .type(HintType.BOOLEAN) + .def("true") + .platform("desktop") + .consumedBy("GenerateDesktopAppWrapperMojo") + .doc("Boolean true/false defaults to true. When set to true some values will ve implicitly " + + "doubled to deal with retina displays and icons etc. Will use higher DPI's")); + + h.add(new Hint("desktop.fullscreen") + .annotatedAs(HintGroup.DESKTOP, "fullscreen") + .type(HintType.BOOLEAN) + .def("false") + .platform("desktop") + .consumedBy("GenerateDesktopAppWrapperMojo") + .doc("Starts the desktop build in full-screen mode.")); + + h.add(new Hint("desktop.height") + .annotatedAs(HintGroup.DESKTOP, "height") + .type(HintType.INT) + .def("600") + .platform("desktop") + .consumedBy("GenerateDesktopAppWrapperMojo") + .doc("Height in pixels for the form in desktop builds, will be doubled for retina grade " + + "displays. Defaults to 600.")); + + h.add(new Hint("desktop.interactiveScrollbars") + .annotatedAs(HintGroup.DESKTOP, "interactiveScrollbars") + .type(HintType.BOOLEAN) + .def("true") + .platform("desktop") + .consumedBy("GenerateDesktopAppWrapperMojo") + .doc("Enables grab-able, click-to-page desktop scrollbars.")); + + h.add(new Hint("desktop.resizable") + .annotatedAs(HintGroup.DESKTOP, "resizable") + .type(HintType.BOOLEAN) + .def("true") + .platform("desktop") + .consumedBy("GenerateDesktopAppWrapperMojo") + .doc("Boolean true/false defaults to true. Indicates whether the UI in the desktop build is " + + "resizable")); + + h.add(new Hint("desktop.title") + .group(HintGroup.DESKTOP) + .type(HintType.STRING) + .platform("desktop") + .consumedBy("GenerateDesktopAppWrapperMojo")); + + h.add(new Hint("desktop.titleBar") + .annotatedAs(HintGroup.DESKTOP, "titleBar") + .values("DesktopTitleBar", "native", "custom", "toolbar") + .def("native") + .platform("desktop") + .consumedBy("GenerateDesktopAppWrapperMojo") + .doc("How the desktop window is framed: native for the OS title bar and menu bar, custom for " + + "an undecorated window with a Codename One drawn title bar, or toolbar for the legacy " + + "in-app Toolbar. An unrecognized value falls back to native with a warning.")); + + h.add(new Hint("desktop.width") + .annotatedAs(HintGroup.DESKTOP, "width") + .type(HintType.INT) + .def("800") + .platform("desktop") + .consumedBy("GenerateDesktopAppWrapperMojo") + .doc("Width in pixels for the form in desktop builds, will be doubled for retina grade " + + "displays. Defaults to 800.")); + + h.add(new Hint("javascript.includeVideoJS") + .group(HintGroup.JAVASCRIPT) + .type(HintType.BOOLEAN) + .def("false") + .platform("javascript") + .consumedBy("JavaScriptBuilder")); + + h.add(new Hint("javascript.inject_proxy") + .group(HintGroup.JAVASCRIPT) + .type(HintType.BOOLEAN) + .def("true") + .platform("javascript") + .consumedBy("JavaScriptProxyPackager") + .doc("true/false (defaults to `true`). The ParparVM builder generates a same-origin proxy " + + "bundle and configures the app to use it. Setting this to `false` disables both proxy " + + "generation and proxy URL injection.")); + + h.add(new Hint("javascript.portSources") + .group(HintGroup.JAVASCRIPT) + .type(HintType.STRING) + .platform("javascript") + .consumedBy("JavaScriptBuilder")); + + h.add(new Hint("javascript.proxy.allowedTargets") + .group(HintGroup.JAVASCRIPT) + .type(HintType.STRING) + .platform("javascript") + .consumedBy("JavaScriptProxyPackager") + .doc("Comma-separated target origins, host names, or wildcard subdomains that a generated " + + "proxy may access, for example `https://api.example.com,*.services.example.org`. If " + + "omitted, the proxy accepts any HTTP or HTTPS target and the build emits a warning.")); + + h.add(new Hint("javascript.proxy.target") + .group(HintGroup.JAVASCRIPT) + .type(HintType.STRING) + .def("jakarta-servlet") + .platform("javascript") + .consumedBy("CN1BuildMojo", "JavaScriptProxyPackager") + .doc("The generated ParparVM proxy deployment platform. Supported values are `jakarta-servlet` " + + "(default), `javax-servlet`, `node`, `php`, `aws-lambda`, `google-cloud-functions`, " + + "`cloudflare-workers`, and `none`.")); + + h.add(new Hint("javascript.proxy.url") + .group(HintGroup.JAVASCRIPT) + .type(HintType.STRING) + .platform("javascript") + .consumedBy("JavaScriptProxyPackager") + .doc("The URL of an existing proxy to use for network requests. Setting it suppresses " + + "generated proxy packaging unless `javascript.proxy.target` is also set. If " + + "`javascript.inject_proxy` is `false`, this build hint is ignored.")); + + h.add(new Hint("linux.arch") + .group(HintGroup.LINUX) + .type(HintType.STRING) + .platform("linux") + .consumedBy("LinuxNativeBuilder")); + + h.add(new Hint("linux.cc") + .group(HintGroup.LINUX) + .type(HintType.STRING) + .platform("linux") + .consumedBy("LinuxNativeBuilder")); + + h.add(new Hint("linux.debug") + .group(HintGroup.LINUX) + .type(HintType.BOOLEAN) + .def("false") + .platform("linux") + .consumedBy("LinuxNativeBuilder")); + + h.add(new Hint("linux.libc") + .group(HintGroup.LINUX) + .type(HintType.STRING) + .def("glibc") + .platform("linux") + .consumedBy("LinuxNativeBuilder")); + + h.add(new Hint("linux.musl") + .group(HintGroup.LINUX) + .type(HintType.BOOLEAN) + .def("false") + .platform("linux") + .consumedBy("LinuxNativeBuilder")); + + h.add(new Hint("linux.muslNativeCc") + .group(HintGroup.LINUX) + .type(HintType.BOOLEAN) + .def("false") + .platform("linux") + .consumedBy("LinuxNativeBuilder")); + + h.add(new Hint("linux.toolchain") + .group(HintGroup.LINUX) + .type(HintType.STRING) + .platform("linux") + .consumedBy("LinuxNativeBuilder")); + + h.add(new Hint("windows.arch") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder") + .doc("Native Windows port only (the `windows-native` build target -- not the JVM `win.*` " + + "desktop hints above). Target CPU architecture for the standalone `.exe`: `x64` (the " + + "default) or `arm64`. Accepts the usual synonyms (`x86_64`/`amd64`, `aarch64`). clang-cl " + + "cross-compiles to the chosen architecture from either host. See the " + + "link:#_working_with_the_native_windows_port[Working with the native Windows port " + + "chapter].")); + + h.add(new Hint("windows.calendar.restrictedCapability") + .group(HintGroup.WINDOWS) + .type(HintType.BOOLEAN) + .def("false") + .platform("windows") + .consumedBy("WindowsNativeBuilder")); + + h.add(new Hint("windows.debug") + .group(HintGroup.WINDOWS) + .type(HintType.BOOLEAN) + .def("false") + .platform("windows") + .consumedBy("WindowsNativeBuilder") + .doc("Native Windows port only. true/false (defaults to false). When `false` the `.exe` is " + + "built optimized and *stripped* -- no PDB, dead-stripped unreferenced code (`/OPT:REF`) " + + "and folded identical functions (`/OPT:ICF`) -- which is the shipping default. Set `true` " + + "to keep debug symbols (a `.pdb` next to the exe, via `RelWithDebInfo` / clang-cl `/Zi` + " + + "linker `/DEBUG`) so a native crash address can be symbolized during development. " + + "Optimizations stay on in both cases.")); + + h.add(new Hint("windows.msix") + .group(HintGroup.WINDOWS) + .type(HintType.BOOLEAN) + .def("false") + .platform("windows") + .consumedBy("WindowsNativeBuilder")); + + h.add(new Hint("windows.msix.identityName") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder")); + + h.add(new Hint("windows.msix.password") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder")); + + h.add(new Hint("windows.msix.pfx") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder")); + + h.add(new Hint("windows.msix.publisher") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder")); + + h.add(new Hint("windows.msix.version") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder")); + + h.add(new Hint("windows.sdkRoot") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder") + .doc("Native Windows port only; used when building on a *non-Windows* host (for example a " + + "Linux build server). Path to a Windows SDK laid out by " + + "https://github.com/Jake-Shadle/xwin[`xwin splat`] (a directory containing `crt/include` " + + "and `sdk/include/um`), used to cross-compile the `.exe` with clang-cl + lld-link instead " + + "of a Visual Studio environment. If unset, the `CN1_XWIN_SYSROOT` environment variable is " + + "used. Ignored on Windows hosts, which build through Visual Studio. The same SDK serves " + + "both `windows.arch` targets (its `x86_64` / `aarch64` lib subdirs).")); + + h.add(new Hint("windows.signing") + .group(HintGroup.WINDOWS) + .type(HintType.BOOLEAN) + .def("true") + .platform("windows") + .consumedBy("WindowsNativeBuilder") + .doc("Native Windows port only. `true`/`false` (default `true`). Set `false` to force an " + + "unsigned build even when a certificate is available.")); + + h.add(new Hint("windows.signing.digest") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .def("sha256") + .platform("windows") + .consumedBy("WindowsNativeBuilder") + .doc("Native Windows port only. Signature digest algorithm. Default `sha256`.")); + + h.add(new Hint("windows.signing.name") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder")); + + h.add(new Hint("windows.signing.password") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder")); + + h.add(new Hint("windows.signing.pkcs12") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder")); + + h.add(new Hint("windows.signing.timestampUrl") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .def("http://timestamp.digicert.com") + .platform("windows") + .consumedBy("WindowsNativeBuilder") + .doc("Native Windows port only. RFC 3161 timestamp server used when signing, so the " + + "signature stays valid after the certificate expires. Default " + + "`http://timestamp.digicert.com`; set empty to disable timestamping.")); + + h.add(new Hint("windows.signing.url") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder")); + } +} diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDynamic.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDynamic.java new file mode 100644 index 00000000000..f82955cf1a4 --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDynamic.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +import com.codename1.build.shared.BuildHints.Hint; + +import java.util.List; + +/** + * Open-ended hint families whose names are built by concatenation, so the set + * of valid keys is unbounded. + * + *

These are deliberately not exposed as annotation attributes. Each + * one is really a map — permission name to setting, entitlement key to + * value — and a Java annotation member cannot express a + * {@code Map}. The shapes that could work (a nested + * {@code @Permission[]}, or a {@code String[]} of {@code "KEY=VALUE"} pairs) + * are a materially different design; until one is chosen these are set through + * {@code codenameone_settings.properties}.

+ * + *

They are catalogued anyway because the drift gate needs them: a mined key + * that matches one of these patterns is accounted for rather than reported as + * an unknown hint.

+ */ +final class BuildHintsDynamic { + + private BuildHintsDynamic() { + } + + static void register(List h) { + family(h, "android.permission.*", "android", "AndroidGradleBuilder", + "true/false. Whether to include a particular permission. Preferred over " + + "android.xpermissions because it avoids conflicts with libraries. See " + + "Android's Manifest.permission documentation for the full list. The " + + "optional .maxSdkVersion suffix becomes the maxSdkVersion attribute of " + + "the generated tag, and .required marks the " + + "permission required."); + family(h, "android.uses_feature.*", "android", "AndroidGradleBuilder", + "Adds a element named by the suffix."); + family(h, "android.uses_permission.*", "android", "AndroidGradleBuilder", + "Adds a element named by the suffix."); + family(h, "android.playService.*", "android", "AndroidGradleBuilder", + "Opts a single Google Play service in or out. The sibling " + + ".minPlayServicesVersion pins its version."); + family(h, "android.cusom_layout*", "android", "AndroidGradleBuilder", + "Numbered custom layout resources: android.cusom_layout1, 2, and so on. " + + "The misspelling is load-bearing -- it is the key the builder " + + "actually reads, so correcting it would silently drop the layout."); + family(h, "ios.NS*UsageDescription", "ios", "IPhoneBuilder", + "Info.plist privacy strings. The commonly used keys are catalogued " + + "individually and exposed through @IosPrivacy; this entry covers the " + + "open tail that the builder sweeps by prefix."); + family(h, "ios.entitlements.*", "ios", "IPhoneBuilder", + "Adds an arbitrary entitlement key to the generated entitlements file."); + family(h, "ios.spm.products.*", "ios", "IPhoneBuilder", + "Selects which products of a Swift Package Manager package to link, keyed " + + "by package identity."); + family(h, "ios.pods.build.*", "ios", "IPhoneBuilder", + "Overrides an Xcode build setting for the generated CocoaPods project."); + family(h, "ios.home.commissioning.buildSettings.*", "ios", "IPhoneBuilder", + "Overrides an Xcode build setting for the Matter commissioning extension."); + family(h, "ios.surfaces.buildSettings.*", "ios", "IPhoneBuilder", + "Overrides an Xcode build setting for the external-surfaces extension."); + family(h, "ios.*.appext.*", "ios", "IPhoneBuilder", + "Per-app-extension signing. ios.debug.appext..* and " + + "ios.release.appext..* are collapsed to unqualified keys before " + + "the request is sent."); + family(h, "harden.*.enabled", "general", "Executor", + "Enables or disables hardening for one platform slice."); + family(h, "harden.*", "general", "Executor", + "The whole hardening namespace is swept into the hardening engine's " + + "configuration, so a hint added there reaches it without a dedicated " + + "reader."); + family(h, "macNative.provisioningProfile.*", "mac", "MacNativeBuilder", + "Per-profile provisioning data for a native macOS build, keyed by profile " + + "name."); + family(h, "var.*", "general", "BuildRequest", + "Defines a variable that any other hint can interpolate as ${var.name}, " + + "with ${var.name:default} for a fallback."); + } + + private static void family(List h, String pattern, String platform, + String consumer, String doc) { + h.add(new Hint(pattern) + .group(HintGroup.NONE) + .type(HintType.STRING) + .dynamic(pattern) + .platform(platform) + .consumedBy(consumer) + .doc(doc)); + } +} diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsExternal.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsExternal.java new file mode 100644 index 00000000000..30c02b89a6e --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsExternal.java @@ -0,0 +1,547 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +import com.codename1.build.shared.BuildHints.Hint; + +import java.util.List; + +/** + * Hints the developer guide documents that nothing in this repository reads. + * + *

Most are consumed by build-daemon lanes whose source is not mirrored here, + * so having no in-repo consumer is not evidence that a hint is dead. A few are + * probably genuinely obsolete. Recording the distinction as + * {@link Hint#isExternal()} keeps both the drift gate and the Settings tool + * honest: the gate does not demand a consumer for these, and the tool still + * offers them for editing.

+ * + *

They are deliberately not annotated. Exposing a hint as a typed attribute + * is a promise that setting it does something, and for these that promise + * cannot be checked from this repository.

+ */ +final class BuildHintsExternal { + + private BuildHintsExternal() { + } + + static void register(List h) { + h.add(new Hint("android.fridaDebugLogging") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .platform("android") + .external() + .doc("Boolean true/false defaults to false. If true, it will add verbose debug logs during " + + "frida detection to show which check if fails on.")); + + h.add(new Hint("android.fridaVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .external() + .doc("x.y.z The version of [frida-blocker](https://github.com/shannah/frida-blocker) to use to " + + "perform frida detection. This is only relevant if `android.fridaDetection=true`. If " + + "omitted, it will use the latest tested version in the build server.")); + + h.add(new Hint("android.signingV1") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .platform("android") + .external() + .doc("true/false Default true. See " + + "https://source.android.com/docs/security/features/apksigning")); + + h.add(new Hint("android.signingV2") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .platform("android") + .external() + .doc("true/false Default true. See " + + "https://source.android.com/docs/security/features/apksigning")); + + h.add(new Hint("android.signingV3") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .platform("android") + .external() + .doc("true/false Default true. See " + + "https://source.android.com/docs/security/features/apksigning")); + + h.add(new Hint("android.signingV4") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .platform("android") + .external() + .doc("true/false Default true. See " + + "https://source.android.com/docs/security/features/apksigning")); + + h.add(new Hint("android.supportV4") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .platform("android") + .external() + .doc("Boolean true/false defaults to false but that can change based on usage (for example, " + + "push implicitly activates this). Indicates whether the android support v4 library should " + + "be included in the build")); + + h.add(new Hint("block_server_registration") + .group(HintGroup.GENERAL) + .type(HintType.BOOLEAN) + .platform("general") + .external() + .doc("true/false flag defaults to false. By default Codename One applications register with " + + "the Codename One server. Setting this to true blocks them from sending information to " + + "the Codename One cloud, which is kept for statistical purposes and may be used to " + + "provide more installation stats in the future.")); + + h.add(new Hint("build.cn1Version") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .external() + .doc("Pro/Enterprise only. Pins the cloud build to a specific released Codename One version " + + "using the Maven release scheme (for example `7.0.182`), or to `master` to build against " + + "the current development head. The build server fetches that version's framework " + + "artifacts. Pro accounts can target versions published within the last two months; " + + "Enterprise within the last six months. Requesting an older version, a version that was " + + "never published, or using this hint without a Pro/Enterprise subscription fails the " + + "build with an explanatory error. See Versioned builds.")); + + h.add(new Hint("codename1.mac.appid") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .external() + .doc("Mac Native cloud builds only. The Mac bundle identifier registered in App Store Connect " + + "/ Apple Developer. Distinct from `codename1.ios.appid` because Apple treats the iOS and " + + "Mac App Store records as separate products. Required for cloud Mac builds.")); + + h.add(new Hint("codename1.mac.certificate") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .external() + .doc("Mac Native cloud builds only. Path to the `.p12` file containing the Mac signing " + + "certificate(s) — _Mac App Distribution_ (3rd Party Mac Developer Application) for App " + + "Store builds, _Developer ID Application_ for Developer ID builds, or both bundled into " + + "the same P12 when `macNative.distribution=both`. Not interchangeable with the iOS " + + "distribution certificate. Required for cloud Mac builds.")); + + h.add(new Hint("codename1.mac.certificatePassword") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .external() + .doc("Mac Native cloud builds only. Password to unlock the P12 referenced by " + + "`codename1.mac.certificate`. Required for cloud Mac builds.")); + + h.add(new Hint("codename1.mac.provision") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .external() + .doc("Mac Native cloud builds only. Path to the Mac provisioning profile " + + "(`.provisionprofile`). Apple issues distinct provisioning profiles for Mac App Store and " + + "Developer ID distribution — pass the one that matches the chosen channel.")); + + h.add(new Hint("desktop.fontSizes") + .group(HintGroup.DESKTOP) + .type(HintType.STRING) + .platform("desktop") + .external() + .doc("Indicates the sizes in pixels for the system fonts as a comma delimited string " + + "containing 3 numbers for small,medium,large fonts.")); + + h.add(new Hint("desktop.mac.cef") + .group(HintGroup.DESKTOP) + .type(HintType.BOOLEAN) + .platform("mac") + .external() + .doc("Whetherto use CEF for media or BrowserComponent instead of JavaFX in Mac desktop builds. " + + "true/false. Default value is `false` (Jan 2021), but this will be changed to `true` in a " + + "future version.")); + + h.add(new Hint("desktop.theme") + .group(HintGroup.DESKTOP) + .type(HintType.STRING) + .platform("desktop") + .external() + .doc("Name of the theme res file (without the \".res\" extension) to use as the \"native\" theme. " + + "By default this is native indicating iOS theme on Mac and Windows Metro on Windows. If " + + "its something else then the app will try to load the file /themeName.res (placed in " + + "native/Java SE directory).")); + + h.add(new Hint("desktop.themeMac") + .group(HintGroup.DESKTOP) + .type(HintType.STRING) + .platform("desktop") + .external() + .doc("Same as `desktop.theme` but specific to macOS")); + + h.add(new Hint("desktop.themeWin") + .group(HintGroup.DESKTOP) + .type(HintType.STRING) + .platform("desktop") + .external() + .doc("Same as `desktop.theme` but specific to Windows")); + + h.add(new Hint("desktop.win.cef") + .group(HintGroup.DESKTOP) + .type(HintType.BOOLEAN) + .platform("desktop") + .external() + .doc("Whether to use CEF for media and BrowserComponent instead of JavaFX in windows desktop " + + "builds. true/false. Default value is `false` (Jan 2021), but this will be changed to " + + "`true` in a future version.")); + + h.add(new Hint("desktop.windowsOutput") + .group(HintGroup.DESKTOP) + .type(HintType.STRING) + .platform("desktop") + .external() + .doc("Can be exe or msi depending on desired results")); + + h.add(new Hint("ios.NSXXXUsageDescription") + .group(HintGroup.IOS_PRIVACY) + .type(HintType.STRING) + .platform("ios") + .external() + .doc("iOS privacy flags for using certain APIs. Starting with Xcode 8, you're required to add " + + "usage description strings for certain APIs. Find a full list of the available keys in " + + "https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html[Apple's " + + "docs]. Some relevant ones include `ios.NSCameraUsageDescription`, " + + "`ios.NSContactsUsageDescription`, `ios.NSLocationAlwaysUsageDescription`, " + + "`NSLocationUsageDescription`, `ios.NSMicrophoneUsageDescription`, " + + "`ios.NSPhotoLibraryAddUsageDescription`, `ios.NSSpeechRecognitionUsageDescription`, " + + "`ios.NSSiriUsageDescription`")); + + h.add(new Hint("ios.appext.NAME.provisioningURL") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .external() + .doc("Cloud device builds only. URL of the provisioning profile for a generic app extension " + + "dropped into `ios/app_extensions/NAME/` (or a generated extension such as `CN1Widgets`), " + + "used when the extension folder doesn't bundle a `.mobileprovision` itself. The profile " + + "is installed on the build machine and added to the export options per bundle id. Used " + + "for both debug and release builds unless a qualified variant (below) is set. An " + + "extension is signed against its own App ID, so a device build with no profile for it -- " + + "by any of the three carriers -- is refused unless the app's own profile is a wildcard " + + "that covers the extension's bundle id.")); + + h.add(new Hint("ios.application_exits") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .platform("ios") + .external() + .doc("true/false (defaults to false). Indicates whether the application should exit on home " + + "button press. The default is to exit, leaving the application running is only tested at " + + "the moment.")); + + h.add(new Hint("ios.debug.archs") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .external() + .doc("Can be set to \"armv7\" to force iOS debug builds to be 32 bit. By default, debug builds " + + "are 64 bit only.")); + + h.add(new Hint("ios.debug.distributionMethod") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .external() + .doc("Specifies distribution type for debug iOS builds only. This is used for enterprise or " + + "ad-hoc builds (using values \"enterprise\" and \"ad-hoc\" respectively).")); + + h.add(new Hint("ios.distributionMethod") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .external() + .doc("Specifies distribution type for debug iOS builds. This is used for enterprise or ad-hoc " + + "builds (using values \"enterprise\" and \"ad-hoc\" respectively).")); + + h.add(new Hint("ios.entitlementsInject") + .group(HintGroup.IOS) + .type(HintType.XML) + .separator("") + .platform("ios") + .external() + .doc("Content to inject into the iOS entitlements file. This should be in the Plist XML " + + "format. See " + + "https://developer.apple.com/documentation/bundleresources/entitlements?language=objc[Apple " + + "Entitlements Documentation].")); + + h.add(new Hint("ios.keychainAccessGroup") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .external() + .doc("Space-delimited list of keychain access groups that this app has access to as described " + + "in " + + "https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html#//apple_ref/doc/uid/TP30000897-CH204-SW11[Apple's " + + "documentation]. These are added to the entitlements file with the key " + + "`keychain-access-groups`.")); + + h.add(new Hint("ios.newPipeline") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .platform("ios") + .external() + .doc("Boolean true/false defaults to true. Allows toggling the OpenGL ES 2.0 drawing pipeline " + + "off to the older OGL ES 1.0 pipeline.")); + + h.add(new Hint("ios.release.archs") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .external() + .doc("Can be set to \"arm64\" to only build iOS release builds for 64 bit. By default, release " + + "builds are both 32 and 64 bit.")); + + h.add(new Hint("ios.release.distributionMethod") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .external() + .doc("Specifies distribution type for release iOS builds only. This is used for enterprise or " + + "ad-hoc builds (using values \"enterprise\" and \"ad-hoc\" respectively).")); + + h.add(new Hint("ios.rpmalloc") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .external() + .doc("`true`/`false` Use https://github.com/rampantpixels/rpmalloc[rpmalloc] instead of " + + "malloc/free for memory allocation in ParparVM. This will cause the deployment target to " + + "be changed to a minimum of iOS 8.0.")); + + h.add(new Hint("ios.statusbar_hidden") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .platform("ios") + .external() + .doc("true/false defaults to false. Hides the iOS status bar if set to true.")); + + h.add(new Hint("ios.testFlight") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .platform("ios") + .external() + .doc("Boolean true/false defaults to false and works only for pro accounts. Enables the " + + "testflight support in the release binaries for easy beta testing. Notice that the IDE " + + "plugin has a \"Test Flight\" check box you *should* use under the iOS section.")); + + h.add(new Hint("ios.xcode_version") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .external() + .doc("The version of Xcode used on the server. Defaults to 4.5; accepts 5.0 as an option and " + + "nothing else.")); + + h.add(new Hint("javascript.inject.afterHead") + .group(HintGroup.JAVASCRIPT) + .type(HintType.STRING) + .platform("javascript") + .external() + .doc("Content to be injected into the index.html file at the end of the `` tag.")); + + h.add(new Hint("javascript.inject.beforeHead") + .group(HintGroup.JAVASCRIPT) + .type(HintType.STRING) + .platform("javascript") + .external() + .doc("Content to be injected into the index.html file at the beginning of the `` tag.")); + + h.add(new Hint("javascript.minifying") + .group(HintGroup.JAVASCRIPT) + .type(HintType.BOOLEAN) + .platform("javascript") + .external() + .doc("true/false (defaults to `true`). By default the JavaScript code is minified to reduce " + + "file size. You may optionally disable minification by setting `javascript.minifying` to " + + "`false`.")); + + h.add(new Hint("javascript.port") + .group(HintGroup.JAVASCRIPT) + .type(HintType.STRING) + .platform("javascript") + .external() + .doc("`parparvm` (default) or `teavm`. Selects the public JavaScript compiler for cloud " + + "builds. `teavm` retains the original builder as a compatibility fallback.")); + + h.add(new Hint("javascript.sourceFilesCopied") + .group(HintGroup.JAVASCRIPT) + .type(HintType.BOOLEAN) + .platform("javascript") + .external() + .doc("true/false (defaults to `false`). Setting this flag to `true` will cause available java " + + "source files to be included in the resulting .zip and .war files. These may be used by " + + "Chrome during debugging.")); + + h.add(new Hint("javascript.stopOnErrors") + .group(HintGroup.JAVASCRIPT) + .type(HintType.BOOLEAN) + .platform("javascript") + .external() + .doc("true/false (defaults to `true`). Causes a TeaVM JavaScript build to fail when the " + + "compiler reports warnings. Setting this to `false` may allow the fallback builder to " + + "complete, but can turn compiler diagnostics into runtime failures that are more " + + "difficult to debug.")); + + h.add(new Hint("javascript.teavm.version") + .group(HintGroup.JAVASCRIPT) + .type(HintType.STRING) + .platform("javascript") + .external() + .doc("(Optional) The version of TeaVM to use for the build. *Use caution*, only use this " + + "property if you know what you're doing!")); + + h.add(new Hint("mac.desktop-vm") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .external() + .doc("The JVM the should be bundled with Mac desktop build. Mac desktop builds only. Supported " + + "values: zuluFx8, zulu11, zuluFx11")); + + h.add(new Hint("macNative.entitlements.allowJit") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .external() + .doc("Mac Native builds only. `true` enables `com.apple.security.cs.allow-jit` for hardened " + + "runtime. ParparVM is AOT-compiled so this is `false` by default; flip when bundling a " + + "JIT-using cn1lib.")); + + h.add(new Hint("macNative.entitlements.appSandbox") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .external() + .doc("Mac Native builds only. `true` enables `com.apple.security.app-sandbox`. Default is " + + "`true` for the `appStore` channel (Mac App Store requires the sandbox), `false` for " + + "`developerID`.")); + + h.add(new Hint("macNative.entitlements.hardenedRuntime") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .external() + .doc("Mac Native builds only. `true` enables hardened runtime restrictions. Default is `true` " + + "for `developerID` (notarization requires it), `false` for `appStore`.")); + + h.add(new Hint("macNative.entitlements.network.client") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .external() + .doc("Mac Native builds only. Toggles `com.apple.security.network.client`. Default `true`.")); + + h.add(new Hint("macNative.entitlements.network.server") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .external() + .doc("Mac Native builds only. Toggles `com.apple.security.network.server`. Default `false`.")); + + h.add(new Hint("macNative.provisioningProfile.appStore") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .external() + .doc("Mac Native builds only. Provisioning profile name for App Store distribution — used only " + + "when `macNative.signing.style=manual`.")); + + h.add(new Hint("macNative.provisioningProfile.developerID") + .group(HintGroup.MAC_NATIVE) + .type(HintType.STRING) + .platform("mac") + .external() + .doc("Mac Native builds only. Provisioning profile name for Developer ID distribution — used " + + "only when `macNative.signing.style=manual`.")); + + h.add(new Hint("win.desktop-vm") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("windows") + .external() + .doc("The JVM that should be bundled in the Windows desktop build. Windows desktop builds " + + "only. Supported values: zulu8, zuluFx8, zulu8-32bit, zuluFx8-32bit, zulu11, zuluFx11, " + + "zulu11-32bit, zuluFx11-32bit")); + + h.add(new Hint("win.installDirName") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("windows") + .external() + .doc("Windows desktop builds only. Overrides the default installation folder name suggested by " + + "the installer (under `Program Files`). Defaults to the application's main class name for " + + "backward compatibility. Use this build hint to set a user-friendly installation folder " + + "name (for example, `win.installDirName=My Application`). The application ID used by " + + "Windows for upgrade detection is unaffected, so existing installations continue to " + + "upgrade.")); + + h.add(new Hint("win.shortcutName") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("windows") + .external() + .doc("Windows desktop builds only. Overrides the name used for the Start Menu shortcut, the " + + "Desktop shortcut and (when `win.launchOnStart=true`) the autostart shortcut. Defaults to " + + "the application's main class name for backward compatibility. Use this build hint to set " + + "a user-friendly shortcut label (for example, `win.shortcutName=My Application`).")); + + h.add(new Hint("win.vm32bit") + .group(HintGroup.GENERAL) + .type(HintType.BOOLEAN) + .platform("windows") + .external() + .doc("true/false (defaults to false). Forces windows desktop builds to use the Win32 JVM " + + "instead of the 64 bit VM making them compatible with older Windows Machines. This is off " + + "by default at the moment because of a bug in JDK 8 update 112 that might cause this to " + + "fail for some cases")); + + h.add(new Hint("windows.extensions") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .external() + .doc("Historical build hint for the discontinued UWP target. It's retained here only for " + + "legacy reference and isn't used by current supported build targets.")); + + h.add(new Hint("xxx.minPlayServicesVersion") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .external() + .doc("This is a special case build hint. You can use any prefix to the build hint and the " + + "convention is to use your cn1lib name. It's identical to " + + "`android.minPlayServicesVersion` with the exception that the \"highest version wins.\" " + + "That way if your cn1lib requires play services 9+ and uses: " + + "`myLib.minPlayServicesVersion=9.0.0` and another library has " + + "`otherLib.minPlayServicesVersion=10.0.0` then play services will be 10.0.0")); + } +} diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java new file mode 100644 index 00000000000..d02748e7855 --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +import com.codename1.build.shared.BuildHints.Hint; + +import java.util.List; + +/** + * Hints with no platform prefix, plus hardening and on-device debugging. + * + *

Seeded by mining every {@code getArg} call site in the builders, so the + * name and the default match what the build actually reads. Curated entries + * carry an annotation attribute and, where the domain is provably closed, an + * enum; the rest are described but set through + * {@code codenameone_settings.properties}.

+ * + *

Split out of {@link BuildHints} because a single class initializer + * holding every entry would exceed the JVM's 64KB per-method limit.

+ */ +final class BuildHintsGeneral { + + private BuildHintsGeneral() { + } + + static void register(List h) { + h.add(new Hint("KeepScreenOn") + .group(HintGroup.GENERAL) + .type(HintType.BOOLEAN) + .def("false") + .platform("general") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("android.onDeviceDebug") + .annotatedAs(HintGroup.ON_DEVICE_DEBUG, "android") + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder", "CN1BuildMojo") + .doc("Boolean true/false defaults to false. When `true`, the generated `AndroidManifest.xml` " + + "is marked `android:debuggable=\"true\"`, R8/proguard is disabled, and the build is pinned " + + "to debug-only (`android.release` is forced off and `android.debug` is forced on) so a " + + "stray hint can't ship a release-signed APK that's `debuggable=\"true\"`. Pair with the " + + "`cn1:android-on-device-debugging` Maven goal (or the bundled IntelliJ run configs) to " + + "install, launch, forward JDWP, and stream logcat through adb. Has no effect on builds " + + "that don't carry it — release builds are unaffected. See the On-Device Debugging " + + "(Android) chapter for the full flow.")); + + h.add(new Hint("androidx.appcompat.version") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("build.incSources") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("CN1BuildMojo")); + + h.add(new Hint("build.testReporter") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("build.unitTest") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("CN1BuildMojo")); + + h.add(new Hint("cn1.androidTheme") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("cn1.buildKey") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("cn1.entitled") + .group(HintGroup.GENERAL) + .type(HintType.BOOLEAN) + .def("true") + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("cn1.harden.forceOff") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("cn1.hardenLevel") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .def("off") + .platform("general") + .consumedBy("AndroidGradleBuilder", "Executor")); + + h.add(new Hint("cn1.hardened") + .group(HintGroup.GENERAL) + .type(HintType.BOOLEAN) + .def("false") + .platform("general") + .consumedBy("AndroidGradleBuilder", "Executor")); + + h.add(new Hint("cn1.hardening.libraryJars") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("cn1.mappingId") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("cn1.nativeTheme") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("AndroidGradleBuilder", "IPhoneBuilder")); + + h.add(new Hint("db.legacy") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("Executor", "GenerateDesktopAppWrapperMojo")); + + h.add(new Hint("delayPushCompletion") + .group(HintGroup.GENERAL) + .type(HintType.BOOLEAN) + .def("false") + .platform("general") + .consumedBy("AndroidGradleBuilder", "IPhoneBuilder")); + + h.add(new Hint("facebook.appId") + .annotatedAs(HintGroup.GENERAL, "facebookAppId") + .type(HintType.STRING) + .def("706695982682332") + .platform("general") + .consumedBy("AndroidGradleBuilder", "IPhoneBuilder") + .doc("The application ID for an app that requires native Facebook login integration, this " + + "defaults to null which means native Facebook support shouldn't be in the app")); + + h.add(new Hint("facebook.clientToken") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("AndroidGradleBuilder") + .doc("The client token for an app that requires native Facebook login integration, this is " + + "required if the facebook.appId is set.")); + + h.add(new Hint("gcm.sender_id") + .annotatedAs(HintGroup.GENERAL, "gcmSenderId") + .type(HintType.STRING) + .platform("general") + .consumedBy("AndroidGradleBuilder") + .doc("The Android/chrome push identifier, see the push section for more details")); + + h.add(new Hint("google.adUnitId") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("AndroidGradleBuilder", "IPhoneBuilder") + .doc("Allows integrating Admob/Google Play ads into the application see " + + "link:https://www.codenameone.com/blog/adding-google-play-ads.html[this]")); + + h.add(new Hint("gradleDependencies") + .group(HintGroup.GENERAL) + .type(HintType.STRING_LIST) + .separator("\n") + .platform("general") + .consumedBy("AndroidGradleBuilder", "MapsProviderInjector")); + + h.add(new Hint("harden.allowUnhardenedLocalBuild") + .annotatedAs(HintGroup.HARDENING, "allowUnhardenedLocalBuild") + .type(HintType.BOOLEAN) + .def("false") + .platform("general") + .consumedBy("CN1BuildMojo") + .doc("Permits a local or source build to run with hardening requested but not applied. Without " + + "it such a build is refused, so a hardened app is never shipped from a target that cannot " + + "actually harden it.")); + + h.add(new Hint("harden.controlFlow") + .annotatedAs(HintGroup.HARDENING, "controlFlow") + .values("HardenControlFlow", "off", "on") + .platform("general") + .consumedBy("CN1BuildMojo") + .doc("Overrides control-flow obfuscation independently of harden.level.")); + + h.add(new Hint("harden.ios.enabled") + .group(HintGroup.HARDENING) + .type(HintType.BOOLEAN) + .def("true") + .platform("general") + .consumedBy("CN1BuildMojo")); + + h.add(new Hint("harden.keep") + .annotatedAs(HintGroup.HARDENING, "keep") + .type(HintType.TEXT_BLOCK) + .platform("general") + .consumedBy("AndroidGradleBuilder") + .doc("Keep rules in ProGuard syntax, one per line, for classes that are resolved by name at " + + "runtime and so cannot be found by the automatic analysis. Same syntax as " + + "android.proguardKeep, so existing rules port directly. Rules are separated by newlines " + + "only, because a semicolon is legal inside a rule body such as { *; }.")); + + h.add(new Hint("harden.level") + .annotatedAs(HintGroup.HARDENING, "level") + .values("HardenLevel", "off", "standard", "aggressive", "paranoid") + .def("off") + .platform("general") + .consumedBy("AndroidGradleBuilder", "CN1BuildMojo", "Executor") + .doc("Master switch for app hardening: off, standard, aggressive or paranoid. An unrecognized " + + "value fails the build rather than being quietly treated as off.")); + + h.add(new Hint("harden.mac.enabled") + .group(HintGroup.HARDENING) + .type(HintType.BOOLEAN) + .def("true") + .platform("general") + .consumedBy("CN1BuildMojo")); + + h.add(new Hint("harden.rename") + .annotatedAs(HintGroup.HARDENING, "rename") + .type(HintType.BOOLEAN) + .platform("general") + .consumedBy("CN1BuildMojo") + .doc("Overrides symbol renaming independently of harden.level.")); + + h.add(new Hint("harden.strings") + .annotatedAs(HintGroup.HARDENING, "strings") + .values("HardenStrings", "off", "constants", "all") + .platform("general") + .consumedBy("CN1BuildMojo") + .doc("Overrides string obfuscation independently of harden.level: off, constants or all.")); + + h.add(new Hint("harden.tv.enabled") + .group(HintGroup.HARDENING) + .type(HintType.BOOLEAN) + .def("true") + .platform("general") + .consumedBy("CN1BuildMojo")); + + h.add(new Hint("harden.watch.enabled") + .group(HintGroup.HARDENING) + .type(HintType.BOOLEAN) + .def("true") + .platform("general") + .consumedBy("CN1BuildMojo")); + + h.add(new Hint("ios.onDeviceDebug") + .annotatedAs(HintGroup.ON_DEVICE_DEBUG, "ios") + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Boolean true/false defaults to false. When `true`, the iOS build links a small JDWP " + + "listener thread (`cn1_debugger`) into the binary and the ParparVM translator emits " + + "source-line and locals metadata so a desktop proxy can serve the running app to any " + + "JDWP-speaking debugger. Has no effect on release builds. See the On-Device Debugging " + + "(iOS) chapter for the full flow.")); + + h.add(new Hint("ios.onDeviceDebug.proxyHost") + .annotatedAs(HintGroup.ON_DEVICE_DEBUG, "iosProxyHost") + .type(HintType.STRING) + .def("127.0.0.1") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Hostname or IP address the device-side listener dials to reach the desktop proxy. " + + "Default `127.0.0.1` (correct for the native iOS simulator). For a physical device, set " + + "this to the developer laptop's LAN IP. Has no effect unless `ios.onDeviceDebug=true`.")); + + h.add(new Hint("ios.onDeviceDebug.proxyPort") + .annotatedAs(HintGroup.ON_DEVICE_DEBUG, "iosProxyPort") + .type(HintType.INT) + .def("55333") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("TCP port on `ios.onDeviceDebug.proxyHost` where the proxy is listening for the device. " + + "Default `55333`. Has no effect unless `ios.onDeviceDebug=true`.")); + + h.add(new Hint("ios.onDeviceDebug.waitForAttach") + .annotatedAs(HintGroup.ON_DEVICE_DEBUG, "iosWaitForAttach") + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Boolean true/false defaults to false. When `true`, the app blocks at startup until the " + + "proxy connects and the IDE tells the VM to continue. Useful when the breakpoint to " + + "investigate fires during app boot. Has no effect unless `ios.onDeviceDebug=true`.")); + + h.add(new Hint("java.version") + .group(HintGroup.GENERAL) + .type(HintType.INT) + .def("8") + .platform("general") + .consumedBy("AndroidGradleBuilder", "CN1BuildMojo", "CreateGameSceneMojo", "InstallCn1libsMojo", "OpenGameBuilderMojo") + .doc("Valid values include 5 or 8. Indicates the JVM version that should be used for server " + + "compilation, this is defined by default for newly created apps based on the Java 8 mode " + + "selection")); + + h.add(new Hint("maps.provider") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("MapsProviderInjector")); + + h.add(new Hint("nativeTheme") + .annotatedAs(HintGroup.GENERAL, "nativeTheme") + .values("NativeThemeMode", "modern", "legacy", "custom") + .platform("general") + .consumedBy("AndroidGradleBuilder", "IPhoneBuilder") + .doc("`modern`, `legacy`, `custom` (default unset). Cross-platform override that sets both " + + "`ios.themeMode` and `and.themeMode` together when those aren't set explicitly. `modern` " + + "= liquid glass + Material 3, `legacy` = iOS 7 flat + Holo Light, `custom` disables the " + + "framework native theme entirely. The legacy alias `cn1.nativeTheme` is still accepted.")); + + h.add(new Hint("noExtraResources") + .annotatedAs(HintGroup.GENERAL, "noExtraResources") + .type(HintType.BOOLEAN) + .def("false") + .platform("general") + .consumedBy("AndroidGradleBuilder", "IPhoneBuilder") + .doc("true/false (defaults to false). Blocks codename one from injecting its own resources " + + "when set to true, the only effect this has is in slightly reducing archive size. This " + + "might have adverse effects on some features of Codename One so it isn't recommended.")); + + h.add(new Hint("requireKotlinStdlib") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("AndroidGradleBuilder")); + + h.add(new Hint("tvMain") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("IPhoneBuilder", "TvNativeBuilder")); + + h.add(new Hint("vserv.allowSkipping") + .group(HintGroup.GENERAL) + .type(HintType.BOOLEAN) + .def("true") + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("vserv.category") + .group(HintGroup.GENERAL) + .type(HintType.INT) + .def("29") + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("vserv.countryCode") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .def("null") + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("vserv.locale") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .def("en_US") + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("vserv.networkCode") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .def("null") + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("vserv.scaleMode") + .group(HintGroup.GENERAL) + .type(HintType.BOOLEAN) + .def("false") + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("vserv.transition") + .group(HintGroup.GENERAL) + .type(HintType.INT) + .def("300000") + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("vserv.zone") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("Executor")); + + h.add(new Hint("watchMain") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("AndroidGradleBuilder", "IPhoneBuilder", "WatchNativeBuilder")); + + h.add(new Hint("watchStandalone") + .group(HintGroup.GENERAL) + .type(HintType.BOOLEAN) + .def("false") + .platform("general") + .consumedBy("AndroidGradleBuilder", "WatchNativeBuilder")); + } +} diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsIos.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsIos.java new file mode 100644 index 00000000000..242951b086b --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsIos.java @@ -0,0 +1,1203 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +import com.codename1.build.shared.BuildHints.Hint; + +import java.util.List; + +/** + * iOS build hints, including the Info.plist privacy strings. + * + *

Seeded by mining every {@code getArg} call site in the builders, so the + * name and the default match what the build actually reads. Curated entries + * carry an annotation attribute and, where the domain is provably closed, an + * enum; the rest are described but set through + * {@code codenameone_settings.properties}.

+ * + *

Split out of {@link BuildHints} because a single class initializer + * holding every entry would exceed the JVM's 64KB per-method limit.

+ */ +final class BuildHintsIos { + + private BuildHintsIos() { + } + + static void register(List h) { + h.add(new Hint("ios.NFCReaderUsageDescription") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.NSBonjourServices") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.NSCalendarsFullAccessUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "calendarsFullAccessUsageDescription") + .type(HintType.STRING) + .def("This app uses your calendars to read and schedule events.") + .platform("ios") + .consumedBy("IPhoneBuilder", "MacNativeBuilder")); + + h.add(new Hint("ios.NSCalendarsUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "calendarsUsageDescription") + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder", "MacNativeBuilder")); + + h.add(new Hint("ios.NSCalendarsWriteOnlyAccessUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "calendarsWriteOnlyAccessUsageDescription") + .type(HintType.STRING) + .def("This app uses your calendar to schedule events.") + .platform("ios") + .consumedBy("IPhoneBuilder", "MacNativeBuilder")); + + h.add(new Hint("ios.NSCameraUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "cameraUsageDescription") + .type(HintType.STRING) + .platform("ios") + .consumedBy("MacNativeBuilder")); + + h.add(new Hint("ios.NSHealthShareUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "healthShareUsageDescription") + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.NSHealthUpdateUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "healthUpdateUsageDescription") + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.NSLocalNetworkUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "localNetworkUsageDescription") + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.NSLocationAlwaysAndWhenInUseUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "locationAlwaysAndWhenInUseUsageDescription") + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.NSLocationAlwaysUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "locationAlwaysUsageDescription") + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.NSLocationWhenInUseUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "locationWhenInUseUsageDescription") + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.NSMicrophoneUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "microphoneUsageDescription") + .type(HintType.STRING) + .platform("ios") + .consumedBy("MacNativeBuilder")); + + h.add(new Hint("ios.NSRemindersFullAccessUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "remindersFullAccessUsageDescription") + .type(HintType.STRING) + .def("This app uses your reminders to read and schedule tasks.") + .platform("ios") + .consumedBy("IPhoneBuilder", "MacNativeBuilder")); + + h.add(new Hint("ios.NSRemindersUsageDescription") + .annotatedAs(HintGroup.IOS_PRIVACY, "remindersUsageDescription") + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder", "MacNativeBuilder")); + + h.add(new Hint("ios.UIRequiredDeviceCapabilities") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.actionSheetStyle") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.add_libs") + .annotatedAs(HintGroup.IOS, "addLibs") + .type(HintType.STRING_LIST) + .separator(";") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("A semicolon separated list of libraries that should be linked to the app to build it")); + + h.add(new Hint("ios.afterFinishLaunching") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Objective-C code that can be injected into the iOS app delegate at the bottom of the " + + "body of the didFinishLaunchingWithOptions callback method")); + + h.add(new Hint("ios.appAttest") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.appAttest.environment") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.appUsesNonExemptEncryption") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.app_groups") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Space-delimited list of app groups that this app belongs to as described in " + + "https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW19[Apple's " + + "documentation]. These are added to the entitlements file with key " + + "`com.apple.security.application-groups`.")); + + h.add(new Hint("ios.applicationDidEnterBackground") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Objective-C code that can be injected into the iOS callback method (message) " + + "`applicationDidEnterBackground`.")); + + h.add(new Hint("ios.applicationQueriesSchemes") + .annotatedAs(HintGroup.IOS, "applicationQueriesSchemes") + .type(HintType.STRING_LIST) + .separator(",") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Comma separated list of url schemes that `canExecute` will respect on iOS. If the url " + + "scheme isn't mentioned here `canExecute` will return false starting with iOS 9. Notice " + + "that this collides with `ios.plistInject` when used with the " + + "`LSApplicationQueriesSchemes...` value so you should use one or the other. " + + "For example, to enable `canExecute` for a url like `myurl://xys` you can use: " + + "`myurl,myotherurl`")); + + h.add(new Hint("ios.associatedDomains") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Comma-delimited list of domains associated with this app. Each domain should be prefixed " + + "by a supported prefix. For example, \"applinks:\" or \"webcredentials:.\" See " + + "https://developer.apple.com/documentation/security/password_autofill/setting_up_an_app_s_associated_domains?language=objc[Apple's " + + "documentation on Associated domains] for more information.")); + + h.add(new Hint("ios.backgroundProcessingIds") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.background_modes") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.beforeFinishLaunching") + .annotatedAs(HintGroup.IOS, "beforeFinishLaunching") + .type(HintType.TEXT_BLOCK) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Objective-C code that can be injected into the iOS app delegate at the top of the body " + + "of the didFinishLaunchingWithOptions callback method")); + + h.add(new Hint("ios.bitcode") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("true/false defaults to false. Enables bitcode support for the build.")); + + h.add(new Hint("ios.blockScreenshotsOnEnterBackground") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("true/false (defaults to false). Indicates that app should prevent iOS from taking " + + "screenshots when app enters background. Described " + + "https://shannah.github.io/cn1-recipes/#_hiding_sensitive_data_when_entering_background[here].")); + + h.add(new Hint("ios.bluetooth.background") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.buildType") + .group(HintGroup.IOS) + .type(HintType.STRING) + .def("debug") + .platform("ios") + .consumedBy("IPhoneBuilder", "WatchNativeBuilder")); + + h.add(new Hint("ios.bundleVersion") + .annotatedAs(HintGroup.IOS, "bundleVersion") + .type(HintType.VERSION) + .platform("ios") + .consumedBy("IPhoneBuilder", "WatchNativeBuilder") + .doc("Indicates the version number of the bundle, this is useful if you want to create a minor " + + "version number change for the beta testing support")); + + h.add(new Hint("ios.carplay.audio") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.carplay.messaging") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.carplay.navigation") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.carplay.poi") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.convertSignalsToExceptions") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.criticalAlerts") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.crypto.gcm") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.debug.teamId") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder", "MacNativeBuilder", "TvNativeBuilder", "WatchNativeBuilder") + .doc("Specifies the team ID associated with the iOS debug provisioning profile and " + + "certificate.")); + + h.add(new Hint("ios.delayPushCompletion") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.dependencyManager") + .annotatedAs(HintGroup.IOS, "dependencyManager") + .values("IosDependencyManager", "auto", "cocoapods", "spm", "both", "none") + .def("auto") + .platform("ios") + .consumedBy("IOSDependencyManager") + .doc("Which native dependency manager to use: auto picks one from whichever of ios.pods and " + + "ios.spm.packages is set, and cocoapods, spm or both require the matching hint to be set. " + + "An unrecognized value fails the build.")); + + h.add(new Hint("ios.deployment_target") + .annotatedAs(HintGroup.IOS, "deploymentTarget") + .type(HintType.VERSION) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Minimum iOS version the build targets. Set it to the lowest iOS you actually support; a " + + "higher value excludes older devices from the App Store listing.")); + + h.add(new Hint("ios.detectJailbreak") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("true/false (defaults to false). When true, the iOS app will exit on launch if it detects " + + "that it's running on a jailbroken device.")); + + h.add(new Hint("ios.devLocale") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.disableScreenshots") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.enableAutoplayVideo") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Boolean true/false defaults to false. Makes videos \"autoplay\" when loaded on iOS")); + + h.add(new Hint("ios.enableBadgeClear") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Boolean true/false defaults to true. Clears the badge value with every load of the app, " + + "this is useful if the app doesn't manually keep track of number values for the badge")); + + h.add(new Hint("ios.enableGalleryMultiselect") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.enableStatusBar7") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.entitlements.com.apple.developer") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.entitlements.com.apple.developer.applesignin") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.entitlements.com.apple.developer.healthkit") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.entitlements.com.apple.developer.homekit") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.entitlements.com.apple.developer.networking.HotspotConfiguration") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.entitlements.com.apple.developer.nfc.hce") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.entitlements.com.apple.developer.nfc.readersession.formats") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.facebook.usePods") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.facebook.version") + .group(HintGroup.IOS) + .type(HintType.STRING) + .def("~>5.6.0") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.facebook_permissions") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Permissions for Facebook used in the Android build target, applicable only if Facebook " + + "native integration is used.")); + + h.add(new Hint("ios.failOnWarning") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.fieldNullChecks") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.fileSharingEnabled") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.firebaseAnalytics") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.firebaseAnalyticsVersion") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.force64") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.generateSplashScreens") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Boolean true/false defaults to false. Enables legacy generation of splash screen images " + + "instead of the current launch storyboards.")); + + h.add(new Hint("ios.glAppDelegateBody") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Objective-C code that can be injected into the iOS app delegate within the body of the " + + "file before the end. This only makes sence for methods that aren't already declared in " + + "the class")); + + h.add(new Hint("ios.glAppDelegateHeader") + .annotatedAs(HintGroup.IOS, "glAppDelegateHeader") + .type(HintType.TEXT_BLOCK) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Objective-C code that can be injected into the iOS app delegate at the top of the file. " + + "For example, if you need to include headers or make special imports for other injected " + + "code")); + + h.add(new Hint("ios.googleAdUnitId") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Allows integrating admob/google play ads, this is effectively identical to " + + "google.adUnitId but only applies to iOS")); + + h.add(new Hint("ios.googleAdUnitIdPadding") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Indicates the amount of padding to pass to the Google Ads placed at the bottom of the " + + "screen with `google.adUnitId`")); + + h.add(new Hint("ios.googleAdUnitTestDevice") + .group(HintGroup.IOS) + .type(HintType.STRING) + .def("97cfc76e5efbc6dfa7eb2e6857b613a0") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.gplus.clientId") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.hceAids") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.headphoneCallback") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Boolean true/false defaults to false. When set to true it assumes the main class has two " + + "methods: `headphonesConnected` & `headphonesDisconnected` which it invokes appropriately " + + "as needed")); + + h.add(new Hint("ios.health.backgroundDelivery") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.health.recalibrateEstimates") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.health.required") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.home.appGroup") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.home.commissioning") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.home.commissioning.displayName") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.home.commissioning.fabric") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.home.commissioning.vendorId") + .group(HintGroup.IOS) + .type(HintType.STRING) + .def("0xFFF1") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.home.required") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.includeNullChecks") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.includePush") + .annotatedAs(HintGroup.IOS, "includePush") + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("true/false (defaults to false). Whether to include the push capabilities in the iOS " + + "build. Notice that the IDE plugin has an \"Include Push\" check box you *should* use under " + + "the iOS section.")); + + h.add(new Hint("ios.intents.appIntents") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.intents.minDeploymentTarget") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.interface_orientation") + .annotatedAs(HintGroup.IOS, "interfaceOrientation") + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("UIInterfaceOrientationPortrait by default. Indicates the orientation, one or more of " + + "(separated by colon :): `UIInterfaceOrientationPortrait`, " + + "`UIInterfaceOrientationPortraitUpsideDown`, `UIInterfaceOrientationLandscapeLeft`, " + + "`UIInterfaceOrientationLandscapeRight`. Notice that the IDE plugin has an \"Interface " + + "Orientation\" combo box you *should* use under the iOS section.")); + + h.add(new Hint("ios.keyboardOpen") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Flips between iOS keyboard open mode and autofold keyboard mode. Defaults to true which " + + "means the keyboard will remain open and not fold automatically when editing moves to " + + "another field.")); + + h.add(new Hint("ios.launchPlaceholder") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.launchStoryboardName") + .group(HintGroup.IOS) + .type(HintType.STRING) + .def("LaunchScreen") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.locationUsageDescription") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder", "WatchNativeBuilder") + .doc("This flag is required for iOS 8 and newer if you're using the location API. It needs to " + + "include a description of the reason for which you need access to the users location")); + + h.add(new Hint("ios.lowMemCamera") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.metal") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Boolean true/false defaults to true. Selects the Metal rendering backend " + + "(`CAMetalLayer`) over the legacy OpenGL ES 2 path (`CAEAGLLayer`). Metal is the " + + "supported iOS graphics API; OpenGL ES is deprecated. Set to `false` to opt out if you " + + "hit a Metal-only rendering regression. See link:#_metal_renderer[Working with iOS / " + + "Metal renderer] for details.")); + + h.add(new Hint("ios.metal.colorSpace") + .group(HintGroup.IOS) + .type(HintType.STRING) + .def("sRGB") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Selects the `CAMetalLayer.colorspace` for the Metal renderer. Accepts `sRGB` (default), " + + "`displayP3`, `deviceRGB`, `linearSRGB`, `extendedSRGB`, `extendedLinearSRGB`, or `none`. " + + "Has no effect when `ios.metal=false`. See " + + "link:#_choosing_a_color_space_for_the_metal_renderer[Working with iOS / Choosing a color " + + "space] for the full table.")); + + h.add(new Hint("ios.minDeploymentTarget") + .annotatedAs(HintGroup.IOS, "minDeploymentTarget") + .type(HintType.VERSION) + .def("6.0") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("The null and empty-string reads of this hint are presence checks; 6.0 is the substantive " + + "default (IPhoneBuilder.java:4671).")); + + h.add(new Hint("ios.mopubAdSize") + .group(HintGroup.IOS) + .type(HintType.STRING) + .def("MOPUB_BANNER_SIZE") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.mopubId") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.mopubTabletAdSize") + .group(HintGroup.IOS) + .type(HintType.STRING) + .def("MOPUB_LEADERBOARD_SIZE") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.mopubTabletId") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.multitasking") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Set to true to enable iOS multitasking and split-screen support. This only works if " + + "`ios.xcode_verson=9.2`.")); + + h.add(new Hint("ios.newStorageLocation") + .annotatedAs(HintGroup.IOS, "newStorageLocation") + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("true/false defaults to false but defined on new projects as true by default. This " + + "changes the storage directory on iOS from using caches to using the documents directory " + + "which is the recommended location but might break compatibility. This is described in " + + "https://github.com/codenameone/CodenameOne/issues/1480[this issue]")); + + h.add(new Hint("ios.noUIWebView") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.no_strip") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.notificationPermissionAtLaunch") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("true/false (defaults to false). Backward-compatibility flag for the pre-issue-#4876 " + + "behavior. By default, the iOS notification permission prompt is deferred until the app " + + "calls `Push.register()` or schedules a `LocalNotification`, matching the Android flow " + + "and giving the developer a chance to display a rationale screen first. Set this hint to " + + "`true` to restore the legacy behavior in which the prompt fires automatically inside " + + "`application:didFinishLaunchingWithOptions:` as soon as the app launches. Existing apps " + + "relying on the prompt being shown at launch should set this to `true`; new apps should " + + "leave it disabled and trigger the prompt explicitly when they're ready to ask for " + + "permission.")); + + h.add(new Hint("ios.objC") + .annotatedAs(HintGroup.IOS, "objC") + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Added the `-ObjC` compile flag to the project files which some native libraries require")); + + h.add(new Hint("ios.openURLInject") + .group(HintGroup.IOS) + .type(HintType.XML) + .separator("") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.optimizer") + .group(HintGroup.IOS) + .type(HintType.STRING) + .def("on") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.plistInject") + .annotatedAs(HintGroup.IOS, "plistInject") + .type(HintType.XML) + .separator("") + .platform("ios") + .consumedBy("IPhoneBuilder", "WatchNativeBuilder") + .doc("entries to inject into the iOS plist file during build.")); + + h.add(new Hint("ios.pods") + .annotatedAs(HintGroup.IOS, "pods") + .type(HintType.STRING_LIST) + .separator(",") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("A comma separated list of https://cocoapods.org/[Cocoa Pods] that should be linked to " + + "the app to build it. For example, `AFNetworking ~> 2.6, ORStackView ~> 3.0, SwiftyJSON " + + "~> 2.3`")); + + h.add(new Hint("ios.pods.build.CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.pods.build.CLANG_ENABLE_MODULES") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.pods.platform") + .annotatedAs(HintGroup.IOS, "podsPlatform") + .type(HintType.VERSION) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Sets the Cocoapods 'platform' for the Cocoapods. Some Cocoapods require a minimum " + + "platform level. For example, `ios.pods.platform=7.0`.")); + + h.add(new Hint("ios.pods.sources") + .annotatedAs(HintGroup.IOS, "podsSources") + .type(HintType.STRING_LIST) + .separator(",") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Extra CocoaPods spec repositories to search, in addition to the default trunk.")); + + h.add(new Hint("ios.pods.use_frameworks!") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.prerendered_icon") + .annotatedAs(HintGroup.IOS, "prerenderedIcon") + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("true/false defaults to false. The iOS build process adapts the submitted icon for iOS " + + "conventions (adding an overlay) that might not be appropriate on some icons. Setting " + + "this to true leaves the icon unchanged (only scaled).")); + + h.add(new Hint("ios.project_type") + .annotatedAs(HintGroup.IOS, "projectType") + .values("IosProjectType", "ios", "ipad", "iphone") + .def("ios") + .platform("ios") + .consumedBy("IPhoneBuilder", "MacNativeBuilder") + .doc("one of ios, ipad, iphone (defaults to ios). Indicates whether the resulting binary is " + + "targeted to the iphone only or ipad only. Notice that the IDE plugin has a \"Project " + + "Type\" combo box you *should* use under the iOS section.")); + + h.add(new Hint("ios.release.teamId") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder", "MacNativeBuilder", "TvNativeBuilder", "WatchNativeBuilder") + .doc("Specifies the team ID associated with the iOS release provisioning profile and " + + "certificate.")); + + h.add(new Hint("ios.shareAppGroup") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.spm.packages") + .annotatedAs(HintGroup.IOS, "spmPackages") + .type(HintType.STRING_LIST) + .separator(";") + .platform("ios") + .consumedBy("IOSDependencyManager", "IPhoneBuilder") + .doc("Swift Package Manager packages to link, one per entry, each written as " + + "identity|url|requirement.")); + + h.add(new Hint("ios.statusBarFG") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.superfastBuild") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.surfaces.appGroup") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.surfaces.deploymentTarget") + .group(HintGroup.IOS) + .type(HintType.VERSION) + .def("16.1") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.surfaces.extension") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.surfaces.frequentUpdates") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.swiftVersion") + .group(HintGroup.IOS) + .type(HintType.VERSION) + .def("5.0") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.teamId") + .annotatedAs(HintGroup.IOS, "teamId") + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder", "MacNativeBuilder", "TvNativeBuilder", "WatchNativeBuilder") + .doc("Specifies the team ID associated with the iOS provisioning profile and certificate. Use " + + "`ios.debug.teamId` and `ios.release.teamId` to specify different team IDs for debug and " + + "release builds respectively.")); + + h.add(new Hint("ios.themeMode") + .annotatedAs(HintGroup.IOS, "themeMode") + .values("IosThemeMode", "auto", "modern", "ios7", "legacy") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("`auto` (default), `modern`, `ios7`, `legacy`. `auto` (unset) keeps the existing iOS 7 " + + "flat theme so pre-refactor screenshot goldens and apps see no behavior change. `modern` " + + "/ `liquid` opts in to the CSS-generated iOS Modern (liquid-glass) theme shipped from " + + "`native-themes/ios-modern/theme.css`. `ios7` / `flat` is the same as `auto` - pre-liquid " + + "iOS 7 flat theme; `legacy` / `iphone` loads the pre-iOS 7 iPhone theme. The `auto` -> " + + "modern flip is planned for a future release.")); + + h.add(new Hint("ios.timeSensitiveNotifications") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.twoDigitVersion") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder", "WatchNativeBuilder")); + + h.add(new Hint("ios.uiscene") + .annotatedAs(HintGroup.IOS, "uiscene") + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("true/false (defaults to true). Enables iOS UIScene lifecycle support. UIScene lets iOS " + + "manage one or more app UI sessions independently, improving lifecycle handling in modern " + + "iOS versions. Apple has indicated UIScene will be required starting with iOS 27, so this " + + "is now on by default; set the flag to `false` only if you need to temporarily fall back " + + "to the legacy `UIApplicationDelegate` lifecycle.")); + + h.add(new Hint("ios.urlScheme") + .annotatedAs(HintGroup.IOS, "urlScheme") + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Allows intercepting a URL call using the syntax `urlPrefix`")); + + h.add(new Hint("ios.urlSchemes") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.useAVKit") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Use AVKit for video components on iOS rather than `MPMoviePlayerController` on iOS " + + "versions 8 through 12. iOS 13 will always use AVKit, and iOS 7 and lower will always use " + + "`MPMoviePlayerController`. Default value `false`")); + + h.add(new Hint("ios.useJavascriptCore") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.usePhotoKitForMultigallery") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.usePrintf") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.useWKWebView") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.usesBackgroundProcessing") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.viewDidLoad") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Objective-C code that can be injected into the iOS callback method (message) " + + "`viewDidLoad`")); + + h.add(new Hint("ios.viewDidLoadInclude") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.wallet.appGroup") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("App Group id starting with `group.` shared by the app and the generated Wallet " + + "extensions. The app publishes pass entries into this group through " + + "`com.codename1.payment.WalletExtension` and the group is added to the app and extension " + + "entitlements automatically. Required when `ios.wallet.extension=true`.")); + + h.add(new Hint("ios.wallet.authEndpoint") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("HTTPS URL the generated login UI extension POSTs `{\"username\",\"password\"}` to; the JSON " + + "response's `token` is stored in the App Group for the provisioning request. Required " + + "when `ios.wallet.includeUI=true`.")); + + h.add(new Hint("ios.wallet.extension") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Boolean true/false defaults to false. Generates an Apple Wallet issuer provisioning " + + "extension (the \"From apps on your iPhone\" flow in the Wallet app) and embeds it in the " + + "build. Requires `ios.wallet.appGroup` and `ios.wallet.issuerEndpoint`. See the Apple " + + "Wallet Extension chapter.")); + + h.add(new Hint("ios.wallet.includeUI") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("false") + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("Boolean true/false defaults to false. Also generates the Wallet authorization UI " + + "extension - a login form shown inside the Wallet app when the app reports that " + + "authentication is required. Requires `ios.wallet.authEndpoint`.")); + + h.add(new Hint("ios.wallet.issuerEndpoint") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("HTTPS URL of the issuer backend endpoint that produces the encrypted provisioning " + + "payload. The generated extension POSTs Apple's certificates/nonce plus the card " + + "identifier and auth token there as JSON. Required when `ios.wallet.extension=true`.")); + + h.add(new Hint("ios.wallet.nonuiExtensionName") + .group(HintGroup.IOS) + .type(HintType.STRING) + .def("WalletNonUIExtension") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.wallet.uiExtensionName") + .group(HintGroup.IOS) + .type(HintType.STRING) + .def("WalletUIExtension") + .platform("ios") + .consumedBy("IPhoneBuilder")); + + h.add(new Hint("ios.zbar_flash") + .group(HintGroup.IOS) + .type(HintType.BOOLEAN) + .def("true") + .platform("ios") + .consumedBy("IPhoneBuilder")); + } +} diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/HintGroup.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/HintGroup.java new file mode 100644 index 00000000000..d10c5eb294a --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/HintGroup.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +/** + * Which annotation type a hint is exposed through, and which section of the + * documentation and the Settings UI it belongs to. + * + *

Assignment is by name prefix, except that two feature groups deliberately + * claim a subtree across platforms: {@link #ON_DEVICE_DEBUG} takes the + * {@code ios.onDeviceDebug*} and {@code android.onDeviceDebug} hints out of + * their platform groups, and {@link #IOS_PRIVACY} takes the literal + * {@code ios.NS*UsageDescription} keys out of {@link #IOS}.

+ * + *

{@link #NONE} means catalogued but not annotated — the hint is still + * described here for the documentation, the Settings tool and the drift gate, + * but it is set through {@code codenameone_settings.properties}. Every dynamic + * hint family is NONE, because a Java annotation cannot express a map.

+ */ +public enum HintGroup { + IOS("Ios", "ios."), + ANDROID("Android", "android."), + DESKTOP("Desktop", "desktop."), + MAC_NATIVE("MacNative", "macNative."), + WINDOWS("Windows", "windows."), + LINUX("Linux", "linux."), + JAVASCRIPT("JavaScript", "javascript."), + TV_NATIVE("TvNative", "tvNative."), + WATCH_NATIVE("WatchNative", "watchNative."), + HARDENING("Hardening", "harden."), + ON_DEVICE_DEBUG("OnDeviceDebug", null), + IOS_PRIVACY("IosPrivacy", null), + /** Unprefixed and one-off-prefix hints, exposed through {@code @Build}. */ + GENERAL("Build", null), + /** Catalogued but not annotated. */ + NONE(null, null); + + private final String annotationSimpleName; + private final String keyPrefix; + + HintGroup(String annotationSimpleName, String keyPrefix) { + this.annotationSimpleName = annotationSimpleName; + this.keyPrefix = keyPrefix; + } + + /** Simple name of the generated annotation type, or null for {@link #NONE}. */ + public String annotationSimpleName() { + return annotationSimpleName; + } + + /** + * The hint-name prefix this group owns, or null when membership is not + * decided by prefix. + */ + public String keyPrefix() { + return keyPrefix; + } + + /** Whether hints in this group are exposed as annotation attributes. */ + public boolean isAnnotated() { + return annotationSimpleName != null; + } +} diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/HintType.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/HintType.java new file mode 100644 index 00000000000..551a6dea287 --- /dev/null +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/HintType.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +/** + * The kind of value a build hint carries. + * + *

This is the single source of truth for hint typing. Three other + * vocabularies used to describe the same thing and drifted apart from each + * other; they are now derived from this one via + * {@link BuildHints#settingsType(HintType)} and + * {@link BuildHints#editorWidget(HintType)}.

+ */ +public enum HintType { + /** {@code "true"} or {@code "false"}. Maps to a Java {@code boolean}. */ + BOOLEAN, + /** A decimal integer. Maps to a Java {@code int}. */ + INT, + /** Free text on a single line. */ + STRING, + /** Free text that is expected to span lines. Same Java type as STRING. */ + TEXT_BLOCK, + /** A delimited list. Maps to {@code String[]}; requires a separator. */ + STRING_LIST, + /** A closed set of values. Maps to a generated Java enum. */ + ENUM, + /** An XML fragment spliced into a manifest or plist. */ + XML, + /** A filesystem path. */ + PATH, + /** An absolute URL. */ + URL, + /** A dotted version number. */ + VERSION, + /** A credential. Never echoed in logs or diagnostics. */ + SECRET +} diff --git a/maven/build-hint-catalog/src/test/java/com/codename1/build/shared/BuildHintsTest.java b/maven/build-hint-catalog/src/test/java/com/codename1/build/shared/BuildHintsTest.java new file mode 100644 index 00000000000..a1b8040a6bb --- /dev/null +++ b/maven/build-hint-catalog/src/test/java/com/codename1/build/shared/BuildHintsTest.java @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.build.shared; + +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * Self-consistency of the build hint catalog. + * + *

Everything downstream is generated from this table, so a defect here + * becomes a broken annotation, a wrong manifest entry, or a hint that silently + * does nothing. These checks are the reason the catalog is Java rather than a + * data file.

+ */ +class BuildHintsTest { + + /** + * Annotation members cannot be named after a public method of Object or + * Annotation: JLS 9.6.1 makes that a compile error, and it is not a keyword + * rule so it is easy to miss until the generated source will not build. + */ + private static final Set ILLEGAL_MEMBER_NAMES = new HashSet(Arrays.asList( + "equals", "hashCode", "toString", "annotationType", "clone", "getClass", + "notify", "notifyAll", "wait", "finalize")); + + private static final Set JAVA_KEYWORDS = new HashSet(Arrays.asList( + "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", + "class", "const", "continue", "default", "do", "double", "else", "enum", + "extends", "final", "finally", "float", "for", "goto", "if", "implements", + "import", "instanceof", "int", "interface", "long", "native", "new", + "package", "private", "protected", "public", "return", "short", "static", + "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", + "transient", "try", "void", "volatile", "while", + "true", "false", "null", "_", "var", "record", "yield", "sealed", "permits")); + + private static final Set LEGAL_SEPARATORS = new HashSet(Arrays.asList( + "", ";", ",", "\n", " ")); + + /** + * The separators {@code LibraryHintMerger} defines today. The catalog has to + * agree with all of them before that map can be deleted in favour of + * {@link BuildHints#separatorFor(String)} -- if the two disagree, a cn1lib's + * contribution is spliced onto the project's value with the wrong delimiter + * and the resulting Gradle or plist fragment is malformed. + */ + private static Map libraryHintMergerSeparators() { + Map m = new LinkedHashMap(); + m.put("android.gradleDep", ";"); + m.put("gradleDependencies", "\n"); + m.put("android.topDependency", "\n"); + m.put("android.repositories", "\n"); + m.put("android.xgradle", "\n"); + m.put("android.gradle.androidx", "\n"); + m.put("android.xgradle_default_config", "\n"); + m.put("android.gradlePlugin", "\n"); + m.put("android.supportv4Dep", "\n"); + m.put("android.proguardKeep", "\n"); + m.put("ios.pods", ","); + m.put("ios.applicationQueriesSchemes", ","); + m.put("ios.add_libs", ";"); + m.put("android.xapplication_attr", " "); + return m; + } + + @Test + void theCatalogIsNotEmpty() { + assertTrue(BuildHints.entries().size() > 400, + "expected the mined hint set, got " + BuildHints.entries().size()); + } + + @Test + void namesAreUniqueAndLookupWorksWithOrWithoutThePrefix() { + for (BuildHints.Hint h : BuildHints.entries()) { + assertSame(h, BuildHints.byName(h.name())); + assertSame(h, BuildHints.byName(BuildHints.ARG_PREFIX + h.name())); + } + } + + private static void assertSame(BuildHints.Hint expected, BuildHints.Hint actual) { + if (expected != actual) { + fail("lookup returned a different entry for " + expected.name()); + } + } + + @Test + void aliasesResolveToARealNonAliasHint() { + for (BuildHints.Hint h : BuildHints.entries()) { + if (h.aliasOf() == null) { + continue; + } + BuildHints.Hint target = BuildHints.byName(h.aliasOf()); + assertNotNull(target, h.name() + " aliases unknown hint " + h.aliasOf()); + assertTrue(target.aliasOf() == null, + h.name() + " aliases " + target.name() + ", which is itself an alias"); + assertEquals(target.name(), BuildHints.canonicalName(h.name())); + } + } + + @Test + void everyAnnotationAttributeIsClaimedExactlyOnce() { + Map claimed = new HashMap(); + for (BuildHints.Hint h : BuildHints.entries()) { + if (!h.isAnnotated()) { + continue; + } + String key = h.group().annotationSimpleName() + "#" + h.attr(); + String previous = claimed.put(key, h.name()); + assertTrue(previous == null, + "@" + key + " is claimed by both " + previous + " and " + h.name()); + } + } + + @Test + void annotationAttributeNamesAreLegalJavaMembers() { + for (BuildHints.Hint h : BuildHints.entries()) { + if (!h.isAnnotated()) { + continue; + } + String a = h.attr(); + assertTrue(a.length() > 0, h.name() + " has an empty attribute name"); + assertTrue(Character.isJavaIdentifierStart(a.charAt(0)), + h.name() + " -> '" + a + "' is not a legal identifier start"); + for (int i = 1; i < a.length(); i++) { + assertTrue(Character.isJavaIdentifierPart(a.charAt(i)), + h.name() + " -> '" + a + "' has an illegal identifier character"); + } + assertFalse(JAVA_KEYWORDS.contains(a), + h.name() + " -> '" + a + "' is a Java keyword"); + assertFalse(ILLEGAL_MEMBER_NAMES.contains(a), + h.name() + " -> '" + a + "' is override-equivalent to a method of " + + "Object or Annotation, which JLS 9.6.1 forbids as an " + + "annotation member name"); + } + } + + @Test + void anAnnotatedHintIsNeverDynamicAndNeverAnAlias() { + for (BuildHints.Hint h : BuildHints.entries()) { + if (!h.isAnnotated()) { + continue; + } + assertFalse(h.isDynamic(), + h.name() + " is a dynamic family; a Java annotation cannot express a map"); + assertTrue(h.aliasOf() == null, + h.name() + " is an alias, so annotating it would create two attributes " + + "for one effective setting"); + } + } + + @Test + void declaredDefaultsMatchTheirDeclaredType() { + for (BuildHints.Hint h : BuildHints.entries()) { + String d = h.def(); + if (d == null || d.length() == 0) { + continue; + } + switch (h.type()) { + case BOOLEAN: + assertTrue("true".equals(d) || "false".equals(d), + h.name() + " is BOOLEAN but defaults to '" + d + "'"); + break; + case INT: + try { + Integer.parseInt(d.trim()); + } catch (NumberFormatException e) { + fail(h.name() + " is INT but defaults to '" + d + "'"); + } + break; + case ENUM: + assertTrue(h.values().contains(d), + h.name() + " defaults to '" + d + "', which is outside its domain " + + h.values()); + break; + default: + break; + } + } + } + + @Test + void everyEnumHasAUsableDomain() { + for (BuildHints.Hint h : BuildHints.entries()) { + if (h.type() != HintType.ENUM) { + continue; + } + assertNotNull(h.enumName(), h.name() + " is ENUM with no enum type name"); + assertTrue(h.values().size() >= 2, + h.name() + " is ENUM with fewer than two values: " + h.values()); + for (String v : h.values()) { + assertFalse(v.indexOf(',') >= 0, + h.name() + " value '" + v + "' contains a comma, which the simulator's " + + "Build Hint editor uses to delimit its value list"); + } + if (!h.valueLabels().isEmpty()) { + assertEquals(h.values().size(), h.valueLabels().size(), + h.name() + " has a label list of a different length to its values"); + } + } + } + + /** + * One-way, deliberately. A list needs a delimiter, but a hint can carry a + * delimiter without being a list the user edits as items -- + * {@code android.xapplication_attr} joins XML attributes with a space. + */ + @Test + void everyListHintHasANonEmptySeparator() { + for (BuildHints.Hint h : BuildHints.entries()) { + if (h.type() == HintType.STRING_LIST) { + assertNotNull(h.separator(), h.name() + " is a list with no separator"); + assertFalse(h.separator().isEmpty(), + h.name() + " is a list with an empty separator, so its values would " + + "run together"); + } + if (h.separator() != null) { + assertTrue(LEGAL_SEPARATORS.contains(h.separator()), + h.name() + " uses an unsupported separator " + quote(h.separator())); + } + } + } + + @Test + void theCatalogAgreesWithLibraryHintMergerOnEverySeparatorItDefines() { + for (Map.Entry e : libraryHintMergerSeparators().entrySet()) { + BuildHints.Hint h = BuildHints.byName(e.getKey()); + assertNotNull(h, "LibraryHintMerger defines a separator for " + e.getKey() + + " but the catalog does not describe it"); + assertEquals(e.getValue(), BuildHints.separatorFor(e.getKey()), + "separator mismatch for " + e.getKey() + ": LibraryHintMerger says " + + quote(e.getValue()) + ", catalog says " + + quote(BuildHints.separatorFor(e.getKey()))); + } + } + + @Test + void anUnknownHintFallsBackToBareConcatenation() { + assertEquals("", BuildHints.separatorFor("some.hint.nobody.catalogued")); + assertEquals("", BuildHints.separatorFor(null)); + } + + @Test + void everyDynamicFamilyDeclaresItsPattern() { + int found = 0; + for (BuildHints.Hint h : BuildHints.entries()) { + if (!h.isDynamic()) { + continue; + } + found++; + assertNotNull(h.pattern(), h.name() + " is dynamic with no pattern"); + assertTrue(h.pattern().indexOf('*') >= 0, + h.name() + " is dynamic but its pattern matches only itself"); + } + assertTrue(found > 10, "expected the known dynamic families, found " + found); + } + + @Test + void derivedTypeVocabulariesCoverEveryHintType() { + Set widgets = new HashSet( + Arrays.asList("TextField", "TextArea", "Checkbox", "Select")); + for (HintType t : HintType.values()) { + assertNotNull(BuildHints.settingsType(t)); + assertTrue(widgets.contains(BuildHints.editorWidget(t)), + t + " maps to '" + BuildHints.editorWidget(t) + + "', which the Build Hint editor does not recognise and would " + + "silently render as a plain text field"); + } + } + + @Test + void everyHintNamesTheCodeThatReadsIt() { + for (BuildHints.Hint h : BuildHints.entries()) { + List by = h.consumedBy(); + assertTrue(!by.isEmpty() || h.isExternal(), + h.name() + " names no consumer and is not marked external(); either it is " + + "read somewhere this catalog does not record, or it is dead"); + } + } + + private static String quote(String s) { + if (s == null) { + return "null"; + } + return "'" + s.replace("\n", "\\n") + "'"; + } +} diff --git a/scripts/build_hint_miner.py b/scripts/build_hint_miner.py index 47498c3547f..a5e7509cd8b 100644 --- a/scripts/build_hint_miner.py +++ b/scripts/build_hint_miner.py @@ -67,7 +67,8 @@ def split_args(text, i): if not fn.endswith(".java"): continue path = os.path.join(dirpath, fn) - text = open(path, encoding="utf-8", errors="replace").read() + with open(path, encoding="utf-8", errors="replace") as fh: + text = fh.read() rel = os.path.relpath(path, ROOT) for pat, prefixed in OPENERS: for m in pat.finditer(text): @@ -97,4 +98,5 @@ def split_args(text, i): if out == "-": json.dump(payload, sys.stdout, indent=1) else: - json.dump(payload, open(out, "w"), indent=1) + with open(out, "w", encoding="utf-8") as fh: + json.dump(payload, fh, indent=1) diff --git a/scripts/check-build-hint-catalog.py b/scripts/check-build-hint-catalog.py index eb8c4c787dc..bb68df8799c 100755 --- a/scripts/check-build-hint-catalog.py +++ b/scripts/check-build-hint-catalog.py @@ -25,7 +25,8 @@ def catalog(): for fn in sorted(os.listdir(src)): if not fn.startswith("BuildHints") or not fn.endswith(".java"): continue - text = open(os.path.join(src, fn), encoding="utf-8").read() + with open(os.path.join(src, fn), encoding="utf-8") as fh: + text = fh.read() for m in re.finditer(r'new Hint\("((?:[^"\\]|\\.)*)"\)', text): names.add(m.group(1)) for m in re.finditer(r'\.dynamic\("((?:[^"\\]|\\.)*)"\)', text): @@ -60,7 +61,8 @@ def documented_hints(): continue path = os.path.join(dirpath, fn) try: - text = open(path, encoding="utf-8", errors="replace").read() + with open(path, encoding="utf-8", errors="replace") as fh: + text = fh.read() except OSError: continue for m in re.finditer(r'codename1\.arg\.([A-Za-z][A-Za-z0-9_.]*)', text): @@ -102,10 +104,11 @@ def main(): baseline = set() if os.path.exists(BASELINE): - for line in open(BASELINE): - line = line.strip() - if line and not line.startswith("#"): - baseline.add(line.split("|")[0]) + with open(BASELINE, encoding="utf-8") as fh: + for line in fh: + line = line.strip() + if line and not line.startswith("#"): + baseline.add(line.split("|")[0]) current = {f.split("|")[0]: f for f in findings} added = sorted(set(current) - baseline) diff --git a/scripts/copyright-header-exclusions.txt b/scripts/copyright-header-exclusions.txt index 77a600506a3..0ef1e55292f 100644 --- a/scripts/copyright-header-exclusions.txt +++ b/scripts/copyright-header-exclusions.txt @@ -27,3 +27,4 @@ vm/ByteCodeTranslator/src/cn1_sqlite3.h | SQLite3 Multiple Ciphers public header vm/ByteCodeTranslator/src/cn1_sqlite3_amalgamation.h | SQLite3 Multiple Ciphers amalgamation, upstream MIT notice over public-domain SQLite Ports/JavaScriptPort/src/main/webapp/js/sqlite3mc.js | SQLite3 Multiple Ciphers WebAssembly loader, Emscripten generated, MIT over public-domain SQLite Ports/JavaScriptPort/src/main/webapp/js/sqlite3-opfs-async-proxy.js | SQLite3 Multiple Ciphers OPFS proxy worker, MIT over public-domain SQLite +maven/cn1app-archetype/src/main/resources/archetype-resources/common/src/main/java/__mainName__.java | Archetype template for the application class of a user's own project, not Codename One source; a GPL header here would be applied to the user's code diff --git a/scripts/fidelity-app/common/src/main/java/com/codenameone/fidelity/FidelityApp.java b/scripts/fidelity-app/common/src/main/java/com/codenameone/fidelity/FidelityApp.java index 5fb34da91d0..53f5f3ac844 100644 --- a/scripts/fidelity-app/common/src/main/java/com/codenameone/fidelity/FidelityApp.java +++ b/scripts/fidelity-app/common/src/main/java/com/codenameone/fidelity/FidelityApp.java @@ -1,11 +1,11 @@ /* * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. - * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Codename One designates this + * published by the Free Software Foundation. Codename One designates this * particular file as subject to the "Classpath" exception as provided - * by Codename One in the LICENSE file that accompanied this code. + * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/scripts/input-validation-app/common/src/main/java/com/codenameone/inputvalidation/InputValidationApp.java b/scripts/input-validation-app/common/src/main/java/com/codenameone/inputvalidation/InputValidationApp.java index 530fd3634f6..b1a0e065416 100644 --- a/scripts/input-validation-app/common/src/main/java/com/codenameone/inputvalidation/InputValidationApp.java +++ b/scripts/input-validation-app/common/src/main/java/com/codenameone/inputvalidation/InputValidationApp.java @@ -1,6 +1,24 @@ /* - * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. */ package com.codenameone.inputvalidation; diff --git a/scripts/purchase-test-app/app/common/src/main/java/com/codenameone/examples/purchasetest/PurchaseTestApp.java b/scripts/purchase-test-app/app/common/src/main/java/com/codenameone/examples/purchasetest/PurchaseTestApp.java index 08cb15458c1..f4453c9d921 100644 --- a/scripts/purchase-test-app/app/common/src/main/java/com/codenameone/examples/purchasetest/PurchaseTestApp.java +++ b/scripts/purchase-test-app/app/common/src/main/java/com/codenameone/examples/purchasetest/PurchaseTestApp.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ package com.codenameone.examples.purchasetest; import com.codename1.payment.Purchase; diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintCatalog.java b/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintCatalog.java index f6191f5d820..4246df1387e 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintCatalog.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintCatalog.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ package com.codename1.settings.hints; import com.codename1.build.shared.BuildHints; diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintMetadata.java b/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintMetadata.java index dcb1cfdc2bc..92e4f72af73 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintMetadata.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintMetadata.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ package com.codename1.settings.hints; import java.util.Collections; diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/project/ProjectBinding.java b/scripts/settings/common/src/main/java/com/codename1/settings/project/ProjectBinding.java index 1f72dafe25f..6b4ea49bfcf 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/project/ProjectBinding.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/project/ProjectBinding.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ package com.codename1.settings.project; public final class ProjectBinding { diff --git a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java index 23a7e8f2a39..38673e3f57e 100644 --- a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java +++ b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ package com.codename1.settings; import com.codename1.settings.hints.BuildHintCatalog; diff --git a/scripts/settings/common/src/test/java/com/codename1/settings/SettingsThemeTest.java b/scripts/settings/common/src/test/java/com/codename1/settings/SettingsThemeTest.java index 51b615d94c5..df308511628 100644 --- a/scripts/settings/common/src/test/java/com/codename1/settings/SettingsThemeTest.java +++ b/scripts/settings/common/src/test/java/com/codename1/settings/SettingsThemeTest.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ package com.codename1.settings; import com.codename1.ui.css.CSSThemeCompiler; diff --git a/tools/build-hint-bootstrap/gen_catalog.py b/tools/build-hint-bootstrap/gen_catalog.py index e1b07755067..d2fb0be54b9 100644 --- a/tools/build-hint-bootstrap/gen_catalog.py +++ b/tools/build-hint-bootstrap/gen_catalog.py @@ -5,9 +5,11 @@ ROOT = "/Users/shai/dev/cn6/CodenameOne" SC = os.path.dirname(os.path.abspath(__file__)) OUT = os.path.join(ROOT, "maven/build-hint-catalog/src/main/java/com/codename1/build/shared") -LICENSE = open(os.path.join(SC, "license.txt")).read() +with open(os.path.join(SC, "license.txt"), encoding="utf-8") as _fh: + LICENSE = _fh.read() -mined = json.load(open(os.path.join(SC, "mined.json"))) +with open(os.path.join(SC, "mined.json"), encoding="utf-8") as _fh: + mined = json.load(_fh) sys.path.insert(0, SC) from curation import CURATED, ENUMS, PRIVACY_PREFIX, DEFAULT_NOTES, DOC_OVERRIDES, TYPE_OVERRIDES @@ -26,7 +28,8 @@ def load_docs(): # This bootstrap is a one-off: the catalog is the source of truth now and is # edited directly. p = os.path.join(SC, "guide_old.asciidoc") - lines = open(p, encoding="utf-8").read().split("\n")[30:736] + with open(p, encoding="utf-8") as fh: + lines = fh.read().split("\n")[30:736] docs, i = {}, 0 while i < len(lines): ln = lines[i] @@ -261,7 +264,8 @@ def wrap(text, indent, width=88): static void register(List h) {{ ''' + "\n\n".join(body) + "\n }\n}\n" - open(os.path.join(OUT, fname + ".java"), "w").write(src) + with open(os.path.join(OUT, fname + ".java"), "w", encoding="utf-8") as fh: + fh.write(src) print("entries per file:", dict(counts), file=sys.stderr) print("total:", sum(counts.values()), file=sys.stderr) diff --git a/tools/build-hint-bootstrap/gen_external.py b/tools/build-hint-bootstrap/gen_external.py index 979fe6de47e..1e6c7fa6cfb 100644 --- a/tools/build-hint-bootstrap/gen_external.py +++ b/tools/build-hint-bootstrap/gen_external.py @@ -10,9 +10,11 @@ ROOT = "/Users/shai/dev/cn6/CodenameOne" OUT = os.path.join(ROOT, "maven/build-hint-catalog/src/main/java/com/codename1/build/shared") -LICENSE = open(os.path.join(SC, "license.txt")).read() +with open(os.path.join(SC, "license.txt"), encoding="utf-8") as _fh: + LICENSE = _fh.read() -mined = set(json.load(open(SC + "/mined.json"))) +with open(SC + "/mined.json", encoding="utf-8") as _fh: + mined = set(json.load(_fh)) PLACEHOLDER = re.compile(r'PERMISSION_NAME|[A-Z_]{4,}$|[<>]') names = sorted(k for k in G.DOCS @@ -62,5 +64,6 @@ static void register(List h) { ''' + "\n\n".join(body) + "\n }\n}\n" -open(os.path.join(OUT, "BuildHintsExternal.java"), "w").write(src) +with open(os.path.join(OUT, "BuildHintsExternal.java"), "w", encoding="utf-8") as _fh: + _fh.write(src) print("external entries:", len(names), file=sys.stderr) From d727c7d976dbd24d885d93e613a7f4cee7132aba Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sat, 22 Aug 2026 21:46:49 +0300 Subject: [PATCH 03/23] Stop the bootstrap doing its work at import time The archived bootstrap ran generation at module scope, so gen_external.py's `import gen_catalog` -- which only wants three helper functions -- rewrote every catalog source as a side effect. Generation and its diagnostics now live in `main()` behind a `__main__` guard, and the module-level file reads became `load_license()` / `load_mined()` / `load_docs()`, so importing does no I/O and cannot fail on inputs the archived copy deliberately does not carry. Verified both directions: importing leaves the catalog untouched, and running the two scripts end to end still reproduces the committed catalog byte for byte. Also drops `json` and `subprocess` from check-build-hint-catalog.py. Both were left from an earlier version that shelled out to the miner instead of importing it. Co-Authored-By: Claude Opus 5 (1M context) --- scripts/check-build-hint-catalog.py | 2 +- tools/build-hint-bootstrap/gen_catalog.py | 146 +++++++++++---------- tools/build-hint-bootstrap/gen_external.py | 8 +- 3 files changed, 85 insertions(+), 71 deletions(-) diff --git a/scripts/check-build-hint-catalog.py b/scripts/check-build-hint-catalog.py index bb68df8799c..14e9506e235 100755 --- a/scripts/check-build-hint-catalog.py +++ b/scripts/check-build-hint-catalog.py @@ -10,7 +10,7 @@ Held against a baseline rather than failing outright: a large tail of hints predates the catalog. The point is that *new* code cannot add another one. """ -import fnmatch, json, os, re, subprocess, sys +import fnmatch, os, re, sys ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.join(ROOT, "scripts")) diff --git a/tools/build-hint-bootstrap/gen_catalog.py b/tools/build-hint-bootstrap/gen_catalog.py index d2fb0be54b9..27c97219313 100644 --- a/tools/build-hint-bootstrap/gen_catalog.py +++ b/tools/build-hint-bootstrap/gen_catalog.py @@ -5,11 +5,13 @@ ROOT = "/Users/shai/dev/cn6/CodenameOne" SC = os.path.dirname(os.path.abspath(__file__)) OUT = os.path.join(ROOT, "maven/build-hint-catalog/src/main/java/com/codename1/build/shared") -with open(os.path.join(SC, "license.txt"), encoding="utf-8") as _fh: - LICENSE = _fh.read() +def load_license(): + with open(os.path.join(SC, "license.txt"), encoding="utf-8") as fh: + return fh.read() -with open(os.path.join(SC, "mined.json"), encoding="utf-8") as _fh: - mined = json.load(_fh) +def load_mined(): + with open(os.path.join(SC, "mined.json"), encoding="utf-8") as fh: + return json.load(fh) sys.path.insert(0, SC) from curation import CURATED, ENUMS, PRIVACY_PREFIX, DEFAULT_NOTES, DOC_OVERRIDES, TYPE_OVERRIDES @@ -48,8 +50,6 @@ def load_docs(): i += 1 return docs -DOCS = load_docs() -print(f"doc rows parsed: {len(DOCS)}", file=sys.stderr) def clean_doc(t): t = re.sub(r'<<[^,>]*,\s*([^>]*)>>', r'\1', t) # <> -> text @@ -184,62 +184,72 @@ def wrap(text, indent, width=88): "BuildHintsGeneral": "Hints with no platform prefix, plus hardening and on-device debugging.", } -# A mined key ending in a dot is the constant half of a concatenation -- -# getArg("android.permission." + name) -- not a hint anyone can set. Cataloguing -# it would put a phantom row in the guide and a phantom entry in the Settings -# tool. Each one is covered by a dynamic family instead. -mined = {k: v for k, v in mined.items() if not k.endswith(".")} - -counts = collections.Counter() -for fname, pred in FILES.items(): - names = sorted(n for n in mined if pred(n)) - counts[fname] = len(names) - body = [] - for n in names: - defaults = [d for d, _, _ in mined[n]] - sites = sorted({os.path.basename(f)[:-5] for _, f, _ in mined[n]}) - doc = clean_doc(DOCS.get(n, "")) - if not doc and n in DOC_OVERRIDES: - doc = DOC_OVERRIDES[n] - if n in DEFAULT_NOTES: - if doc and not doc.rstrip().endswith((".", "!", "?")): - doc = doc.rstrip() + "." - doc = (doc + " " + DEFAULT_NOTES[n]).strip() - htype, lit, sep = infer(n, defaults, doc) - parts = [' h.add(new Hint("%s")' % jesc(n)] - g = group_of(n) - cur = CURATED.get(n) - enum_name = None - if g == "IOS_PRIVACY": - parts.append(' .annotatedAs(HintGroup.IOS_PRIVACY, "%s")' % privacy_attr(n)) - htype = "STRING" - elif cur: - cg, attr, enum_name, forced_type, forced_def = cur - parts.append(' .annotatedAs(HintGroup.%s, "%s")' % (cg, attr)) - if forced_type: - htype = forced_type - if forced_def is not None: - lit = forced_def - else: - parts.append(' .group(HintGroup.%s)' % g) - if enum_name: - vals = ", ".join('"%s"' % v for v in ENUMS[enum_name]) - parts.append(' .values("%s", %s)' % (enum_name, vals)) - if lit is not None and lit not in ENUMS[enum_name]: - lit = None - else: - parts.append(' .type(HintType.%s)' % htype) - if lit is not None and lit != "": - parts.append(' .def("%s")' % jesc(lit)) - if sep is not None: - parts.append(' .separator("%s")' % jesc(sep)) - parts.append(' .platform("%s")' % platform_of(n)) - parts.append(' .consumedBy(%s)' % ", ".join('"%s"' % s for s in sites)) - if doc: - parts.append(' .doc(%s)' % wrap(doc, 24)) - body.append("\n".join(parts) + ");") - - src = LICENSE + f'''package com.codename1.build.shared; +def main(): + """Emit the BuildHints* registration classes. + + Guarded rather than run at import: gen_external.py imports this module for + load_docs/clean_doc/infer, and without the guard that import would rewrite + every catalog source as a side effect. + """ + LICENSE = load_license() + DOCS = load_docs() + print(f"doc rows parsed: {len(DOCS)}", file=sys.stderr) + # A mined key ending in a dot is the constant half of a concatenation -- + # getArg("android.permission." + name) -- not a hint anyone can set. + # Cataloguing it would put a phantom row in the guide and a phantom entry in + # the Settings tool. Each one is covered by a dynamic family instead. + mined = {k: v for k, v in load_mined().items() if not k.endswith(".")} + + counts = collections.Counter() + for fname, pred in FILES.items(): + names = sorted(n for n in mined if pred(n)) + counts[fname] = len(names) + body = [] + for n in names: + defaults = [d for d, _, _ in mined[n]] + sites = sorted({os.path.basename(f)[:-5] for _, f, _ in mined[n]}) + doc = clean_doc(DOCS.get(n, "")) + if not doc and n in DOC_OVERRIDES: + doc = DOC_OVERRIDES[n] + if n in DEFAULT_NOTES: + if doc and not doc.rstrip().endswith((".", "!", "?")): + doc = doc.rstrip() + "." + doc = (doc + " " + DEFAULT_NOTES[n]).strip() + htype, lit, sep = infer(n, defaults, doc) + parts = [' h.add(new Hint("%s")' % jesc(n)] + g = group_of(n) + cur = CURATED.get(n) + enum_name = None + if g == "IOS_PRIVACY": + parts.append(' .annotatedAs(HintGroup.IOS_PRIVACY, "%s")' % privacy_attr(n)) + htype = "STRING" + elif cur: + cg, attr, enum_name, forced_type, forced_def = cur + parts.append(' .annotatedAs(HintGroup.%s, "%s")' % (cg, attr)) + if forced_type: + htype = forced_type + if forced_def is not None: + lit = forced_def + else: + parts.append(' .group(HintGroup.%s)' % g) + if enum_name: + vals = ", ".join('"%s"' % v for v in ENUMS[enum_name]) + parts.append(' .values("%s", %s)' % (enum_name, vals)) + if lit is not None and lit not in ENUMS[enum_name]: + lit = None + else: + parts.append(' .type(HintType.%s)' % htype) + if lit is not None and lit != "": + parts.append(' .def("%s")' % jesc(lit)) + if sep is not None: + parts.append(' .separator("%s")' % jesc(sep)) + parts.append(' .platform("%s")' % platform_of(n)) + parts.append(' .consumedBy(%s)' % ", ".join('"%s"' % s for s in sites)) + if doc: + parts.append(' .doc(%s)' % wrap(doc, 24)) + body.append("\n".join(parts) + ");") + + src = LICENSE + f'''package com.codename1.build.shared; import com.codename1.build.shared.BuildHints.Hint; @@ -264,8 +274,12 @@ def wrap(text, indent, width=88): static void register(List h) {{ ''' + "\n\n".join(body) + "\n }\n}\n" - with open(os.path.join(OUT, fname + ".java"), "w", encoding="utf-8") as fh: - fh.write(src) + with open(os.path.join(OUT, fname + ".java"), "w", encoding="utf-8") as fh: + fh.write(src) + + print("entries per file:", dict(counts), file=sys.stderr) + print("total:", sum(counts.values()), file=sys.stderr) + -print("entries per file:", dict(counts), file=sys.stderr) -print("total:", sum(counts.values()), file=sys.stderr) +if __name__ == "__main__": + main() diff --git a/tools/build-hint-bootstrap/gen_external.py b/tools/build-hint-bootstrap/gen_external.py index 1e6c7fa6cfb..6794244504d 100644 --- a/tools/build-hint-bootstrap/gen_external.py +++ b/tools/build-hint-bootstrap/gen_external.py @@ -10,21 +10,21 @@ ROOT = "/Users/shai/dev/cn6/CodenameOne" OUT = os.path.join(ROOT, "maven/build-hint-catalog/src/main/java/com/codename1/build/shared") -with open(os.path.join(SC, "license.txt"), encoding="utf-8") as _fh: - LICENSE = _fh.read() +LICENSE = G.load_license() with open(SC + "/mined.json", encoding="utf-8") as _fh: mined = set(json.load(_fh)) +DOCS = G.load_docs() PLACEHOLDER = re.compile(r'PERMISSION_NAME|[A-Z_]{4,}$|[<>]') -names = sorted(k for k in G.DOCS +names = sorted(k for k in DOCS if k not in mined and not PLACEHOLDER.search(k) and "." in k or (k not in mined and not PLACEHOLDER.search(k) and k.islower())) names = sorted(set(n for n in names if not PLACEHOLDER.search(n))) body = [] for n in names: - doc = G.clean_doc(G.DOCS[n]) + doc = G.clean_doc(DOCS[n]) htype, lit, sep = G.infer(n, [], doc) parts = [' h.add(new Hint("%s")' % G.jesc(n)] parts.append(' .group(HintGroup.%s)' % G.group_of(n)) From 96bff9038a0f71f6d557f7012844d6df9ed68338 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sat, 22 Aug 2026 23:06:32 +0300 Subject: [PATCH 04/23] Make the generated docs and sources survive the ASCII and prose gates Three separate gates rejected generated output. Each is fixed in the generator so the class of problem cannot come back through a catalog edit. Unmappable characters. The prose is imported from the developer guide, which uses typographic punctuation, and `CodenameOne/src` is also compiled by an Ant javac step with ASCII encoding where a single em dash is `error: unmappable character for encoding ASCII` -- a build failure, not a warning. A Unicode escape would not have helped: javac expands `\uXXXX` before it strips comments, so the character reappears. `toAscii` now folds the punctuation that actually occurs, and *refuses* anything it has no mapping for rather than dropping it, because silently deleting a character from a hint's documentation is the worse outcome. Broken table. `ios.spm.packages` is documented as `identity|url|requirement`, and a bare `|` starts a new AsciiDoc cell, so asciidoctor reported "dropping cells from incomplete row" for the whole 529-row table. Cells are escaped now. Vale. The guide enforces the Microsoft style as errors, and the generated table feeds it, so the catalog's prose has to satisfy it too: contractions, no "and so on", no stray adverbs. A default value is not prose, though -- the one remaining hit was `android.file_paths`, whose default is an XML fragment -- so a quoted default now carries the `// vale-skip:` comment .vale.ini documents for individual false positives. Also fixes a data bug the guide exposed. The miner preserved Java escape sequences instead of decoding them, so `android.file_paths` and `android.facebook_permissions` recorded defaults containing literal backslashes that the build never sees, and those reached the rendered table. The miner decodes escapes and re-quotes safely, and the two catalog entries are corrected. Co-Authored-By: Claude Opus 5 (1M context) --- .../annotations/buildhints/Hardening.java | 6 +- .../annotations/buildhints/OnDeviceDebug.java | 4 +- .../impl/javase/BuildHintCatalogDefaults.java | 8 +- .../Advanced-Topics-Under-The-Hood.asciidoc | 2 +- .../_generated-build-hints.adoc | 16 ++-- .../build/shared/BuildHintCodeGenerator.java | 94 +++++++++++++++++-- .../build/shared/BuildHintsAndroid.java | 4 +- .../build/shared/BuildHintsDynamic.java | 7 +- .../build/shared/BuildHintsGeneral.java | 8 +- scripts/build_hint_miner.py | 23 ++++- tools/build-hint-bootstrap/gen_catalog.py | 4 +- 11 files changed, 139 insertions(+), 37 deletions(-) diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/Hardening.java b/CodenameOne/src/com/codename1/annotations/buildhints/Hardening.java index c9190a591fd..657ef4e737a 100644 --- a/CodenameOne/src/com/codename1/annotations/buildhints/Hardening.java +++ b/CodenameOne/src/com/codename1/annotations/buildhints/Hardening.java @@ -43,21 +43,21 @@ /// Permits a local or source build to run with hardening requested but not /// applied. Without it such a build is refused, so a hardened app is never - /// shipped from a target that cannot actually harden it. + /// shipped from a target that can't actually harden it. boolean allowUnhardenedLocalBuild() default false; /// Overrides control-flow obfuscation independently of harden.level. HardenControlFlow controlFlow() default HardenControlFlow.OFF; /// Keep rules in ProGuard syntax, one per line, for classes that are resolved - /// by name at runtime and so cannot be found by the automatic analysis. Same + /// by name at runtime and so can't be found by the automatic analysis. Same /// syntax as android.proguardKeep, so existing rules port directly. Rules are /// separated by newlines only, because a semicolon is legal inside a rule body /// such as { *; }. String keep() default ""; /// Master switch for app hardening: off, standard, aggressive or paranoid. An - /// unrecognized value fails the build rather than being quietly treated as off. + /// unrecognized value fails the build rather than being treated as off. HardenLevel level() default HardenLevel.OFF; /// Overrides symbol renaming independently of harden.level. diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java b/CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java index ef5fca7085a..21c7a20e283 100644 --- a/CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java +++ b/CodenameOne/src/com/codename1/annotations/buildhints/OnDeviceDebug.java @@ -48,8 +48,8 @@ /// release-signed APK that's `debuggable="true"`. Pair with the /// `cn1:android-on-device-debugging` Maven goal (or the bundled IntelliJ run /// configs) to install, launch, forward JDWP, and stream logcat through adb. - /// Has no effect on builds that don't carry it — release builds are unaffected. - /// See the On-Device Debugging (Android) chapter for the full flow. + /// Has no effect on builds that don't carry it -- release builds are + /// unaffected. See the On-Device Debugging (Android) chapter for the full flow. boolean android() default false; /// Boolean true/false defaults to false. When `true`, the iOS build links a diff --git a/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java b/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java index 477dbc68ce8..8a8014201c3 100644 --- a/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java +++ b/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java @@ -244,7 +244,7 @@ static void register() { set("{{@OnDeviceDebug}}.label", "On-Device Debugging"); set("{{#OnDeviceDebug#android.onDeviceDebug}}.label", "Android"); set("{{#OnDeviceDebug#android.onDeviceDebug}}.type", "Checkbox"); - set("{{#OnDeviceDebug#android.onDeviceDebug}}.description", "Boolean true/false defaults to false. When `true`, the generated `AndroidManifest.xml` is marked `android:debuggable=\"true\"`, R8/proguard is disabled, and the build is pinned to debug-only (`android.release` is forced off and `android.debug` is forced on) so a stray hint can't ship a release-signed APK that's `debuggable=\"true\"`. Pair with the `cn1:android-on-device-debugging` Maven goal (or the bundled IntelliJ run configs) to install, launch, forward JDWP, and stream logcat through adb. Has no effect on builds that don't carry it — release builds are unaffected. See the On-Device Debugging (Android) chapter for the full flow."); + set("{{#OnDeviceDebug#android.onDeviceDebug}}.description", "Boolean true/false defaults to false. When `true`, the generated `AndroidManifest.xml` is marked `android:debuggable=\"true\"`, R8/proguard is disabled, and the build is pinned to debug-only (`android.release` is forced off and `android.debug` is forced on) so a stray hint can't ship a release-signed APK that's `debuggable=\"true\"`. Pair with the `cn1:android-on-device-debugging` Maven goal (or the bundled IntelliJ run configs) to install, launch, forward JDWP, and stream logcat through adb. Has no effect on builds that don't carry it -- release builds are unaffected. See the On-Device Debugging (Android) chapter for the full flow."); set("{{#OnDeviceDebug#ios.onDeviceDebug}}.label", "Ios"); set("{{#OnDeviceDebug#ios.onDeviceDebug}}.type", "Checkbox"); set("{{#OnDeviceDebug#ios.onDeviceDebug}}.description", "Boolean true/false defaults to false. When `true`, the iOS build links a small JDWP listener thread (`cn1_debugger`) into the binary and the ParparVM translator emits source-line and locals metadata so a desktop proxy can serve the running app to any JDWP-speaking debugger. Has no effect on release builds. See the On-Device Debugging (iOS) chapter for the full flow."); @@ -276,18 +276,18 @@ static void register() { set("{{@Hardening}}.label", "App Hardening"); set("{{#Hardening#harden.allowUnhardenedLocalBuild}}.label", "Allow unhardened local build"); set("{{#Hardening#harden.allowUnhardenedLocalBuild}}.type", "Checkbox"); - set("{{#Hardening#harden.allowUnhardenedLocalBuild}}.description", "Permits a local or source build to run with hardening requested but not applied. Without it such a build is refused, so a hardened app is never shipped from a target that cannot actually harden it."); + set("{{#Hardening#harden.allowUnhardenedLocalBuild}}.description", "Permits a local or source build to run with hardening requested but not applied. Without it such a build is refused, so a hardened app is never shipped from a target that can't actually harden it."); set("{{#Hardening#harden.controlFlow}}.label", "Control flow"); set("{{#Hardening#harden.controlFlow}}.type", "Select"); set("{{#Hardening#harden.controlFlow}}.values", "off,on"); set("{{#Hardening#harden.controlFlow}}.description", "Overrides control-flow obfuscation independently of harden.level."); set("{{#Hardening#harden.keep}}.label", "Keep"); set("{{#Hardening#harden.keep}}.type", "TextArea"); - set("{{#Hardening#harden.keep}}.description", "Keep rules in ProGuard syntax, one per line, for classes that are resolved by name at runtime and so cannot be found by the automatic analysis. Same syntax as android.proguardKeep, so existing rules port directly. Rules are separated by newlines only, because a semicolon is legal inside a rule body such as { *; }."); + set("{{#Hardening#harden.keep}}.description", "Keep rules in ProGuard syntax, one per line, for classes that are resolved by name at runtime and so can't be found by the automatic analysis. Same syntax as android.proguardKeep, so existing rules port directly. Rules are separated by newlines only, because a semicolon is legal inside a rule body such as { *; }."); set("{{#Hardening#harden.level}}.label", "Level"); set("{{#Hardening#harden.level}}.type", "Select"); set("{{#Hardening#harden.level}}.values", "off,standard,aggressive,paranoid"); - set("{{#Hardening#harden.level}}.description", "Master switch for app hardening: off, standard, aggressive or paranoid. An unrecognized value fails the build rather than being quietly treated as off."); + set("{{#Hardening#harden.level}}.description", "Master switch for app hardening: off, standard, aggressive or paranoid. An unrecognized value fails the build rather than being treated as off."); set("{{#Hardening#harden.rename}}.label", "Rename"); set("{{#Hardening#harden.rename}}.type", "Checkbox"); set("{{#Hardening#harden.rename}}.description", "Overrides symbol renaming independently of harden.level."); diff --git a/docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc b/docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc index fb3dd6f1703..ead34ed89a4 100644 --- a/docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc +++ b/docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc @@ -32,7 +32,7 @@ Most of the commonly used hints also have a compiler-checked form: an annotation in `com.codename1.annotations.buildhints` that you put on the application's main class. Written that way a misspelled name is an unknown symbol and an unsupported value is an unknown enum constant, instead of a properties line that -is accepted, never read, and silently does nothing. The Annotation column below +is accepted, never read, and has no effect. The Annotation column below names that form where one exists. Setting the same hint both ways fails the build. diff --git a/docs/developer-guide/_generated-build-hints.adoc b/docs/developer-guide/_generated-build-hints.adoc index 38586afdbfd..2d540549aad 100644 --- a/docs/developer-guide/_generated-build-hints.adoc +++ b/docs/developer-guide/_generated-build-hints.adoc @@ -278,7 +278,7 @@ |string |_(none)_ |_(properties file only)_ -|Numbered custom layout resources: android.cusom_layout1, 2, and so on. The misspelling is load-bearing -- it is the key the builder actually reads, so correcting it would silently drop the layout. +|Numbered custom layout resources: android.cusom_layout1, android.cusom_layout2 and upward. The misspelling is load-bearing: it's the key the builder actually reads, so correcting it drops the layout with no warning. |android.cusom_layout1 |string @@ -366,13 +366,15 @@ |android.facebook_permissions |string -|`\"public_profile\",\"email\",\"user_friends\"` +// vale-skip: Microsoft.Quotes: this is a literal default value, not prose -- the quotes belong to the value. +|`"public_profile","email","user_friends"` |_(none)_ |Permissions for Facebook used in the Android build target, applicable only if Facebook native integration is used. |android.file_paths |string -|` ` +// vale-skip: Microsoft.Quotes: this is a literal default value, not prose -- the quotes belong to the value. +|` ` |_(none)_ | @@ -1454,7 +1456,7 @@ |boolean |`false` |`@Hardening(allowUnhardenedLocalBuild)` -|Permits a local or source build to run with hardening requested but not applied. Without it such a build is refused, so a hardened app is never shipped from a target that cannot actually harden it. +|Permits a local or source build to run with hardening requested but not applied. Without it such a build is refused, so a hardened app is never shipped from a target that can't actually harden it. |harden.controlFlow |`off`, `on` @@ -1472,13 +1474,13 @@ |text_block |_(none)_ |`@Hardening(keep)` -|Keep rules in ProGuard syntax, one per line, for classes that are resolved by name at runtime and so cannot be found by the automatic analysis. Same syntax as android.proguardKeep, so existing rules port directly. Rules are separated by newlines only, because a semicolon is legal inside a rule body such as { *; }. +|Keep rules in ProGuard syntax, one per line, for classes that are resolved by name at runtime and so can't be found by the automatic analysis. Same syntax as android.proguardKeep, so existing rules port directly. Rules are separated by newlines only, because a semicolon is legal inside a rule body such as { *; }. |harden.level |`off`, `standard`, `aggressive`, `paranoid` |`off` |`@Hardening(level)` -|Master switch for app hardening: off, standard, aggressive or paranoid. An unrecognized value fails the build rather than being quietly treated as off. +|Master switch for app hardening: off, standard, aggressive or paranoid. An unrecognized value fails the build rather than being treated as off. |harden.mac.enabled |boolean @@ -2486,7 +2488,7 @@ |list (`;` delimited) |_(none)_ |`@Ios(spmPackages)` -|Swift Package Manager packages to link, one per entry, each written as identity|url|requirement. +|Swift Package Manager packages to link, one per entry, each written as identity\|url\|requirement. |ios.spm.products.* |string diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java index 9b130800487..60864ab4ef8 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java @@ -494,7 +494,7 @@ private static String simulatorSchemaSource(Map for (Map.Entry> e : byGroup.entrySet()) { String group = e.getKey().annotationSimpleName(); sb.append("\n set(\"{{@").append(group).append("}}.label\", ") - .append(quote(groupLabel(e.getKey()))).append(");\n"); + .append(quote(toAscii(groupLabel(e.getKey())))).append(");\n"); for (BuildHints.Hint h : e.getValue()) { String key = "{{#" + group + "#" + h.name() + "}}"; sb.append(" set(\"").append(key).append(".label\", ") @@ -514,7 +514,7 @@ private static String simulatorSchemaSource(Map } if (h.doc() != null && h.doc().length() > 0) { sb.append(" set(\"").append(key).append(".description\", ") - .append(quote(h.doc())).append(");\n"); + .append(quote(toAscii(h.doc()))).append(");\n"); } } } @@ -558,10 +558,19 @@ public int compare(BuildHints.Hint a, BuildHints.Hint b) { for (BuildHints.Hint h : all) { // Dynamic families are listed too: their names are patterns rather than // keys, but they are real settings a reader needs to find. - sb.append('|').append(h.name()).append('\n'); - sb.append('|').append(adocType(h)).append('\n'); + sb.append('|').append(cell(h.name())).append('\n'); + sb.append('|').append(cell(adocType(h))).append('\n'); + // A default is a literal value, not prose. One containing a quote -- + // android.file_paths defaults to an XML fragment -- trips Vale's + // Microsoft.Quotes rule, which the developer guide enforces as an + // error. Protect just that line using the mechanism .vale.ini + // documents for individual false positives. + if (h.def() != null && h.def().indexOf('"') >= 0) { + sb.append("// vale-skip: Microsoft.Quotes: this is a literal default value, ") + .append("not prose -- the quotes belong to the value.\n"); + } sb.append('|').append(h.def() == null || h.def().length() == 0 - ? "_(none)_" : "`" + h.def() + "`").append('\n'); + ? "_(none)_" : "`" + cell(h.def()) + "`").append('\n'); sb.append('|').append(h.isAnnotated() ? "`@" + h.group().annotationSimpleName() + "(" + h.attr() + ")`" : (h.isDynamic() ? "_(properties file only)_" : "_(none)_")).append('\n'); @@ -572,12 +581,25 @@ public int compare(BuildHints.Hint a, BuildHints.Hint b) { + "repository, so there is no in-repo reference for it." : ""; } - sb.append('|').append(doc).append("\n\n"); + sb.append('|').append(cell(doc)).append("\n\n"); } sb.append("|===\n"); return sb.toString(); } + /** + * Escapes a value for an AsciiDoc table cell. + * + *

A bare {@code |} starts a new cell, so a hint whose documentation + * contains one -- {@code ios.spm.packages} is written + * {@code identity|url|requirement} -- silently shifts every following column + * and asciidoctor reports "dropping cells from incomplete row" for the whole + * table.

+ */ + private static String cell(String text) { + return text == null ? "" : text.replace("|", "\\|"); + } + private static String adocType(BuildHints.Hint h) { if (h.type() == HintType.ENUM) { StringBuilder sb = new StringBuilder(); @@ -698,9 +720,56 @@ private static String markdownType(BuildHints.Hint h) { return javaType(h); } + /** + * Folds text to ASCII. + * + *

The prose is imported from the developer guide, which uses typographic + * punctuation. {@code CodenameOne/src} is also compiled by an Ant javac step + * with ASCII encoding, where a single em dash is + * {@code error: unmappable character for encoding ASCII} -- a build failure, + * not a warning. A Unicode escape would not help: javac processes + * {@code \\uXXXX} before it strips comments, so the character would simply + * reappear.

+ */ + static String toAscii(String text) { + if (text == null) { + return null; + } + StringBuilder sb = new StringBuilder(text.length()); + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + switch (c) { + case '\u2014': sb.append("--"); break; // em dash + case '\u2013': sb.append('-'); break; // en dash + case '\u2018': + case '\u2019': sb.append('\''); break; // curly single quotes + case '\u201c': + case '\u201d': sb.append('"'); break; // curly double quotes + case '\u2026': sb.append("..."); break; // ellipsis + case '\u2192': sb.append("->"); break; // right arrow + case '\u00d7': sb.append('x'); break; // multiplication sign + case '\u00a0': sb.append(' '); break; // non-breaking space + default: + if (c < 0x80) { + sb.append(c); + break; + } + // Refuse rather than drop it. Silently deleting a character + // from a hint's documentation is a worse outcome than telling + // whoever edited the catalog to add a mapping here. + throw new IllegalArgumentException("Build hint documentation contains '" + + c + "' (U+" + Integer.toHexString(c).toUpperCase() + + "), which has no ASCII equivalent in toAscii(). The Ant javac step " + + "compiles CodenameOne/src as ASCII and rejects it as unmappable. " + + "Add a mapping, or reword the text."); + } + } + return sb.toString(); + } + /** Wraps text as /// markdown doc comment lines. */ private static String doc(String text, String indent) { - String clean = text.replace("@since", "since").replaceAll("\\s+", " ").trim(); + String clean = toAscii(text).replace("@since", "since").replaceAll("\\s+", " ").trim(); StringBuilder sb = new StringBuilder(); StringBuilder line = new StringBuilder(); for (String word : clean.split(" ")) { @@ -732,6 +801,17 @@ private static String esc(String s) { } private static void write(File f, String content) throws IOException { + if (f.getName().endsWith(".java")) { + for (int i = 0; i < content.length(); i++) { + if (content.charAt(i) >= 0x80) { + throw new IOException(f.getName() + " would contain the non-ASCII character '" + + content.charAt(i) + "' (U+" + + Integer.toHexString(content.charAt(i)).toUpperCase() + + "), which the Ant javac step rejects as unmappable. Add it to " + + "toAscii()."); + } + } + } File parent = f.getParentFile(); if (parent != null && !parent.isDirectory() && !parent.mkdirs()) { throw new IOException("Could not create " + parent); diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java index 240be102a79..ccf306ecffc 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java @@ -483,7 +483,7 @@ static void register(List h) { h.add(new Hint("android.facebook_permissions") .group(HintGroup.ANDROID) .type(HintType.STRING) - .def("\\\"public_profile\\\",\\\"email\\\",\\\"user_friends\\\"") + .def("\"public_profile\",\"email\",\"user_friends\"") .platform("android") .consumedBy("AndroidGradleBuilder") .doc("Permissions for Facebook used in the Android build target, applicable only if Facebook " @@ -492,7 +492,7 @@ static void register(List h) { h.add(new Hint("android.file_paths") .group(HintGroup.ANDROID) .type(HintType.STRING) - .def(" ") + .def(" ") .platform("android") .consumedBy("AndroidGradleBuilder")); diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDynamic.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDynamic.java index f82955cf1a4..9f3a99ee178 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDynamic.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDynamic.java @@ -63,9 +63,10 @@ static void register(List h) { "Opts a single Google Play service in or out. The sibling " + ".minPlayServicesVersion pins its version."); family(h, "android.cusom_layout*", "android", "AndroidGradleBuilder", - "Numbered custom layout resources: android.cusom_layout1, 2, and so on. " - + "The misspelling is load-bearing -- it is the key the builder " - + "actually reads, so correcting it would silently drop the layout."); + "Numbered custom layout resources: android.cusom_layout1, android.cusom_layout2 " + + "and upward. The misspelling is load-bearing: it's the key the " + + "builder actually reads, so correcting it drops the layout with " + + "no warning."); family(h, "ios.NS*UsageDescription", "ios", "IPhoneBuilder", "Info.plist privacy strings. The commonly used keys are catalogued " + "individually and exposed through @IosPrivacy; this entry covers the " diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java index d02748e7855..d1d5a46a4e5 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java @@ -206,8 +206,8 @@ static void register(List h) { .platform("general") .consumedBy("CN1BuildMojo") .doc("Permits a local or source build to run with hardening requested but not applied. Without " - + "it such a build is refused, so a hardened app is never shipped from a target that cannot " - + "actually harden it.")); + + "it such a build is refused, so a hardened app is never shipped from a target that " + + "can't actually harden it.")); h.add(new Hint("harden.controlFlow") .annotatedAs(HintGroup.HARDENING, "controlFlow") @@ -229,7 +229,7 @@ static void register(List h) { .platform("general") .consumedBy("AndroidGradleBuilder") .doc("Keep rules in ProGuard syntax, one per line, for classes that are resolved by name at " - + "runtime and so cannot be found by the automatic analysis. Same syntax as " + + "runtime and so can't be found by the automatic analysis. Same syntax as " + "android.proguardKeep, so existing rules port directly. Rules are separated by newlines " + "only, because a semicolon is legal inside a rule body such as { *; }.")); @@ -240,7 +240,7 @@ static void register(List h) { .platform("general") .consumedBy("AndroidGradleBuilder", "CN1BuildMojo", "Executor") .doc("Master switch for app hardening: off, standard, aggressive or paranoid. An unrecognized " - + "value fails the build rather than being quietly treated as off.")); + + "value fails the build rather than being treated as off.")); h.add(new Hint("harden.mac.enabled") .group(HintGroup.HARDENING) diff --git a/scripts/build_hint_miner.py b/scripts/build_hint_miner.py index a5e7509cd8b..3f4699dac82 100644 --- a/scripts/build_hint_miner.py +++ b/scripts/build_hint_miner.py @@ -22,13 +22,28 @@ (re.compile(r'\bgetProperty\(\s*"codename1\.arg\.'), True), ] +_ESCAPES = {'n': '\n', 't': '\t', 'r': '\r', 'b': '\b', 'f': '\f', + '"': '"', "'": "'", '\\': '\\'} + + def read_literal(text, i): - """Read a Java string literal body starting just after the opening quote.""" + """Read a Java string literal starting just after the opening quote. + + Escape sequences are decoded, not preserved. Keeping them verbatim recorded + android.file_paths' default as `` -- + backslashes the build never sees -- which then reached the developer guide. + """ out = [] while i < len(text): c = text[i] if c == '\\': - out.append(text[i:i+2]); i += 2; continue + nxt = text[i + 1] if i + 1 < len(text) else '' + if nxt == 'u': + try: + out.append(chr(int(text[i + 2:i + 6], 16))); i += 6; continue + except ValueError: + pass + out.append(_ESCAPES.get(nxt, nxt)); i += 2; continue if c == '"': return "".join(out), i + 1 out.append(c); i += 1 @@ -41,7 +56,9 @@ def split_args(text, i): c = text[i] if c == '"': lit, j = read_literal(text, i + 1) - cur.append('"' + (lit or "") + '"'); i = j; continue + # Re-quote with proper escaping so a decoded inner quote does not + # break the literal-default check below. + cur.append(json.dumps(lit or "", ensure_ascii=False)); i = j; continue if c == "'": j = i + 1 while j < len(text) and text[j] != "'": diff --git a/tools/build-hint-bootstrap/gen_catalog.py b/tools/build-hint-bootstrap/gen_catalog.py index 27c97219313..9015d1fbe11 100644 --- a/tools/build-hint-bootstrap/gen_catalog.py +++ b/tools/build-hint-bootstrap/gen_catalog.py @@ -105,7 +105,9 @@ def infer(name, defaults, doc): lit = None for x in d: if x.startswith('"') and x.endswith('"'): - lit = x[1:-1]; break + # json.loads, not a slice: the miner re-quotes with real escaping, so + # a naive strip would leave backslashes the build never sees. + lit = json.loads(x); break if x in ("true", "false") or re.fullmatch(r'-?\d+', x): lit = x; break dl = doc.lower() From a343fe33358d88f8ee639121d3efba136031fc5a Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sat, 22 Aug 2026 23:54:32 +0300 Subject: [PATCH 05/23] Give ThreadSafeDatabaseTest headroom under the FormTest timeout `killedThreadReportsItselfFinished` failed the Java 21 leg with "FormTest timed out after 5000ms; edt=initialized pendingSerialCalls=0". The waits in this class used a 5000ms deadline, which is exactly the `@FormTest` timeout in EDTTestInterceptor -- so on a loaded runner the poll loop consumed the entire harness budget and the interceptor fired first. The report then said only that the method timed out, with nothing about which condition never became true. The waits now use 2000ms, well inside the harness budget and still roughly two thousand times the ~1ms these threads actually take to stop. A genuine regression now fails on the test's own assertion, which names what went wrong. Pre-existing (the test arrived with #5526) and unrelated to the build hint work: core-unittests has no dependency on the JavaSE port, so none of the simulator registration in this branch runs there, this branch changes nothing under com.codename1.db or EasyThread, and the Java 8 leg passed the same commit. Co-Authored-By: Claude Opus 5 (1M context) --- .../codename1/db/ThreadSafeDatabaseTest.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/maven/core-unittests/src/test/java/com/codename1/db/ThreadSafeDatabaseTest.java b/maven/core-unittests/src/test/java/com/codename1/db/ThreadSafeDatabaseTest.java index 162675b7636..ae786cb60b5 100644 --- a/maven/core-unittests/src/test/java/com/codename1/db/ThreadSafeDatabaseTest.java +++ b/maven/core-unittests/src/test/java/com/codename1/db/ThreadSafeDatabaseTest.java @@ -30,6 +30,19 @@ public class ThreadSafeDatabaseTest extends UITestBase { + /** + * How long a test waits for a worker thread to stop. + * + *

Deliberately below the 5000ms {@code @FormTest} timeout in + * {@link com.codename1.junit.EDTTestInterceptor}. These waits used to use + * 5000ms as well, so a slow runner spent the whole harness budget inside the + * poll loop and the interceptor fired first: the report was + * "FormTest timed out after 5000ms" with nothing about which condition never + * became true. With headroom the test fails on its own assertion instead, + * which names the thing that went wrong.

+ */ + private static final long WORKER_STOP_TIMEOUT_MILLIS = 2000; + @FormTest public void testDelegation() throws Exception { Database db = TestCodenameOneImplementation.getInstance().openOrCreateDB("test_threadsafe.db"); @@ -91,7 +104,7 @@ public void run() { } } }); - long deadline = System.currentTimeMillis() + 5000; + long deadline = System.currentTimeMillis() + WORKER_STOP_TIMEOUT_MILLIS; while (!tsDb.getThread().isFinished() && System.currentTimeMillis() < deadline) { Thread.sleep(10); } @@ -118,7 +131,7 @@ public void killedThreadReportsItselfFinished() throws Exception { com.codename1.util.EasyThread et = com.codename1.util.EasyThread.start("test-kill-flag"); Assertions.assertFalse(et.isFinished(), "a running thread is not finished"); et.kill(); - long deadline = System.currentTimeMillis() + 5000; + long deadline = System.currentTimeMillis() + WORKER_STOP_TIMEOUT_MILLIS; while (!et.isFinished() && System.currentTimeMillis() < deadline) { Thread.sleep(10); } @@ -150,7 +163,7 @@ public void closingAfterTheWorkerHasGoneStaysQuiet() throws Exception { .openOrCreateDB("test_threadsafe_close_after_worker.db"); ThreadSafeDatabase tsDb = new ThreadSafeDatabase(db); tsDb.getThread().killWhenIdle(); - long deadline = System.currentTimeMillis() + 5000; + long deadline = System.currentTimeMillis() + WORKER_STOP_TIMEOUT_MILLIS; while (!tsDb.getThread().isFinished() && System.currentTimeMillis() < deadline) { Thread.sleep(10); } @@ -202,7 +215,7 @@ public void run() { }); synchronized (started) { while (!started[0]) { - started.wait(5000); + started.wait(WORKER_STOP_TIMEOUT_MILLIS); } } From 0edef42ca46a387f5a6830e439f74180b3cd5df1 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 00:52:08 +0300 Subject: [PATCH 06/23] Refuse to migrate a project that never runs process-annotations A mojo's defaultPhase does not bind it to a project -- the project's POM has to -- and nothing turns a build hint annotation back into a codename1.arg.* pair except the process-annotations goal. So migrating a project without that binding deleted working properties and replaced them with annotations no goal ever reads: the hints vanished from the build with no diagnostic anywhere. Five projects in this branch were already in that state. gamebuilder, docs/demos, video-builder and cn1playground bind the plugin but not that goal, so the binding is added. input-validation-app's common module has no build section at all, so its migration is reverted rather than inventing a lifecycle for a demo app. The goal now checks the reactor for the binding and refuses with the execution block to paste, so this cannot happen to anyone else. Three more from the same review: - The deletion pass recognized only `key=value`. `Properties.load` also accepts `key:value`, `key value`, escaped separators inside the key, and logical continuation lines; a declaration it failed to match was left behind while the annotation was added, so the next build failed with the duplicate-hint error this goal exists to prevent. Keys are parsed the way Properties.load defines them now, with a unit test per form. - The settings file was read as ISO-8859-1 and written back as UTF-8, turning any unrelated non-ASCII byte -- an accented displayName, say -- into mojibake. It is written back as ISO-8859-1. - cn1.androidTheme and cn1.nativeTheme are deprecated aliases of and.themeMode and nativeTheme, which the builders honour as fallbacks. Neither declared aliasOf, so conflict detection missed them and one value silently won. Also: the generation script rebuilt the generator only when its class was absent, so editing a catalog source and rerunning regenerated every view from the previous build's bytecode -- reporting success while ignoring the edit, and passing --check on a tree that was genuinely stale. It always rebuilds now. Co-Authored-By: Claude Opus 5 (1M context) --- docs/demos/common/pom.xml | 1 + .../_generated-build-hints.adoc | 4 +- .../build/shared/BuildHintsGeneral.java | 14 +- .../maven/MigrateBuildHintsMojo.java | 161 ++++++++++++++++-- .../MigrateBuildHintsPropertyParsingTest.java | 92 ++++++++++ .../BuildHintAnnotationProcessorTest.java | 13 ++ scripts/build_hint_miner.py | 4 + scripts/cn1playground/common/pom.xml | 1 + scripts/gamebuilder/common/pom.xml | 1 + scripts/gen-build-hint-annotations.sh | 10 +- .../common/codenameone_settings.properties | 3 + .../inputvalidation/InputValidationApp.java | 23 +-- scripts/video-builder/common/pom.xml | 8 +- 13 files changed, 290 insertions(+), 45 deletions(-) create mode 100644 maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java diff --git a/docs/demos/common/pom.xml b/docs/demos/common/pom.xml index 40104bae6ec..3f1b32b5884 100644 --- a/docs/demos/common/pom.xml +++ b/docs/demos/common/pom.xml @@ -350,6 +350,7 @@ compliance-check css + process-annotations diff --git a/docs/developer-guide/_generated-build-hints.adoc b/docs/developer-guide/_generated-build-hints.adoc index 2d540549aad..d23082316d4 100644 --- a/docs/developer-guide/_generated-build-hints.adoc +++ b/docs/developer-guide/_generated-build-hints.adoc @@ -1324,7 +1324,7 @@ |string |_(none)_ |_(none)_ -| +|Deprecated alias for and.themeMode (AndroidGradleBuilder.java:4097). Both names configure one setting, so declaring this alongside @Android(themeMode) is a conflict. |cn1.buildKey |string @@ -1372,7 +1372,7 @@ |string |_(none)_ |_(none)_ -| +|Deprecated alias for nativeTheme (AndroidGradleBuilder.java:4099, IPhoneBuilder.java:947). Both names configure one setting, so declaring this alongside @Build(nativeTheme) is a conflict. |codename1.mac.appid |string diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java index d1d5a46a4e5..c85cf6117a0 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java @@ -91,10 +91,15 @@ static void register(List h) { .consumedBy("CN1BuildMojo")); h.add(new Hint("cn1.androidTheme") + .aliasOf("and.themeMode") + .deprecated("Use and.themeMode, or @Android(themeMode = ...).") .group(HintGroup.GENERAL) .type(HintType.STRING) .platform("general") - .consumedBy("AndroidGradleBuilder")); + .consumedBy("AndroidGradleBuilder") + .doc("Deprecated alias for and.themeMode (AndroidGradleBuilder.java:4097). " + + "Both names configure one setting, so declaring this alongside " + + "@Android(themeMode) is a conflict.")); h.add(new Hint("cn1.buildKey") .group(HintGroup.GENERAL) @@ -142,10 +147,15 @@ static void register(List h) { .consumedBy("Executor")); h.add(new Hint("cn1.nativeTheme") + .aliasOf("nativeTheme") + .deprecated("Use nativeTheme, or @Build(nativeTheme = ...).") .group(HintGroup.GENERAL) .type(HintType.STRING) .platform("general") - .consumedBy("AndroidGradleBuilder", "IPhoneBuilder")); + .consumedBy("AndroidGradleBuilder", "IPhoneBuilder") + .doc("Deprecated alias for nativeTheme (AndroidGradleBuilder.java:4099, " + + "IPhoneBuilder.java:947). Both names configure one setting, so " + + "declaring this alongside @Build(nativeTheme) is a conflict.")); h.add(new Hint("db.legacy") .group(HintGroup.GENERAL) diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index a9f7ab5280e..6ecc9fc579a 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -99,6 +99,25 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException throw new MojoExecutionException("No codenameone_settings.properties in " + projectDir); } + // Nothing turns an annotation back into a build hint except the + // process-annotations goal, and a mojo's defaultPhase does not bind it to + // a project -- the project's own POM has to. Migrating without that + // binding deletes working properties and replaces them with annotations no + // goal ever reads, so the hints disappear from the build silently. + if (!processAnnotationsIsBound()) { + throw new MojoFailureException("This project does not run the cn1 process-annotations " + + "goal, so build hint annotations would never be turned back into the " + + "codename1.arg.* pairs the builders read, and migrating would silently drop " + + "them.\n\nAdd it to the common module's POM first:\n" + + " \n" + + " cn1-process-classes\n" + + " process-classes\n" + + " \n" + + " process-annotations\n" + + " \n" + + " "); + } + // The annotations ship in codenameone-core. A project pinned to a release // that predates them would migrate cleanly here and then fail to compile, // so refuse rather than hand back a broken project. @@ -211,6 +230,38 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException + new File(mainSource).getName()); } + /** + * Whether any module in the reactor binds the {@code process-annotations} + * goal. + * + *

Checked across the reactor rather than on {@code project} because this + * goal is an aggregator, so {@code project} is the root POM while the binding + * lives in the common module.

+ */ + private boolean processAnnotationsIsBound() { + java.util.List projects = reactorProjects; + if (projects == null || projects.isEmpty()) { + projects = java.util.Collections.singletonList(project); + } + for (org.apache.maven.project.MavenProject p : projects) { + java.util.List plugins = p.getBuildPlugins(); + if (plugins == null) { + continue; + } + for (org.apache.maven.model.Plugin plugin : plugins) { + if (!"codenameone-maven-plugin".equals(plugin.getArtifactId())) { + continue; + } + for (org.apache.maven.model.PluginExecution e : plugin.getExecutions()) { + if (e.getGoals() != null && e.getGoals().contains("process-annotations")) { + return true; + } + } + } + } + return false; + } + /** * Whether the codenameone-core on this project's compile classpath actually * carries the annotations. @@ -445,10 +496,27 @@ static int classDeclarationIndex(String text, boolean kotlin, String simpleName) * Deletes the migrated lines, leaving every other line -- comments, * ordering, unrelated settings -- byte for byte as it was. */ + /** + * Deletes the migrated declarations, leaving every other line -- comments, + * ordering, unrelated settings -- byte for byte as it was. + * + *

Keys are recognised the way {@code Properties.load} defines them, not + * just {@code key=value}: {@code key:value} and {@code key value} are equally + * valid, and a line ending in an odd number of backslashes continues onto the + * next. A declaration this pass fails to recognise is left behind while the + * annotation is added, and the very next build fails with the duplicate-hint + * error this goal exists to avoid.

+ * + *

Written back as ISO-8859-1 because that is what {@code Properties.load} + * reads a {@code .properties} stream as. Rewriting the file as UTF-8 would + * turn any non-ASCII byte elsewhere in it -- an accented + * {@code codename1.displayName}, say -- into mojibake, even though it has + * nothing to do with the hint being migrated.

+ */ private void removeMigratedLines(File settingsFile, List keys) throws IOException { List lines = new ArrayList(); BufferedReader r = new BufferedReader( - new InputStreamReader(new FileInputStream(settingsFile), "ISO-8859-1")); + new InputStreamReader(new FileInputStream(settingsFile), PROPERTIES_ENCODING)); try { String line; while ((line = r.readLine()) != null) { @@ -457,27 +525,92 @@ private void removeMigratedLines(File settingsFile, List keys) throws IO } finally { r.close(); } + Map wanted = new LinkedHashMap(); for (String k : keys) { wanted.put(k, Boolean.TRUE); } + StringBuilder out = new StringBuilder(); - for (String line : lines) { - String t = line.trim(); - boolean drop = false; - if (t.length() > 0 && t.charAt(0) != '#' && t.charAt(0) != '!') { - int eq = t.indexOf('='); - int colon = t.indexOf(':'); - int split = eq < 0 ? colon : (colon < 0 ? eq : Math.min(eq, colon)); - if (split > 0 && wanted.containsKey(t.substring(0, split).trim())) { - drop = true; - } + for (int i = 0; i < lines.size(); i++) { + // Gather the whole logical line: continuations belong to the same + // declaration and have to go with it. + int last = i; + StringBuilder logical = new StringBuilder(lines.get(i)); + while (continues(lines.get(last)) && last + 1 < lines.size()) { + last++; + logical.append(lines.get(last).replaceFirst("^\\s+", "")); } - if (!drop) { - out.append(line).append('\n'); + String key = propertyKeyOf(logical.toString()); + if (key != null && wanted.containsKey(key)) { + i = last; + continue; } + for (int j = i; j <= last; j++) { + out.append(lines.get(j)).append('\n'); + } + i = last; + } + writeProperties(settingsFile, out.toString()); + } + + /** Whether a physical line ends in an odd number of backslashes. */ + private static boolean continues(String line) { + int backslashes = 0; + for (int i = line.length() - 1; i >= 0 && line.charAt(i) == '\\'; i--) { + backslashes++; + } + return backslashes % 2 == 1; + } + + /** + * The key a logical properties line declares, or null when the line is blank + * or a comment. + * + *

Follows {@code java.util.Properties}: the key runs to the first + * unescaped {@code =}, {@code :} or whitespace.

+ */ + static String propertyKeyOf(String logicalLine) { + int i = 0; + while (i < logicalLine.length() && isPropertySpace(logicalLine.charAt(i))) { + i++; + } + if (i >= logicalLine.length()) { + return null; + } + char first = logicalLine.charAt(i); + if (first == '#' || first == '!') { + return null; + } + StringBuilder key = new StringBuilder(); + for (; i < logicalLine.length(); i++) { + char c = logicalLine.charAt(i); + if (c == '\\' && i + 1 < logicalLine.length()) { + key.append(logicalLine.charAt(++i)); + continue; + } + if (c == '=' || c == ':' || isPropertySpace(c)) { + break; + } + key.append(c); + } + return key.length() == 0 ? null : key.toString(); + } + + private static boolean isPropertySpace(char c) { + return c == ' ' || c == '\t' || c == '\f'; + } + + /** The encoding {@code Properties.load(InputStream)} reads. */ + private static final String PROPERTIES_ENCODING = "ISO-8859-1"; + + private static void writeProperties(File f, String content) throws IOException { + Writer w = new OutputStreamWriter(new FileOutputStream(f), PROPERTIES_ENCODING); + try { + w.write(content); + } finally { + w.close(); } - write(settingsFile, out.toString()); } private static String read(File f) throws IOException { diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java new file mode 100644 index 00000000000..136d6faae4f --- /dev/null +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.maven; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +/// Covers the properties parsing in `MigrateBuildHintsMojo`. +/// +/// The migration deletes a hint's declaration and replaces it with an +/// annotation. A declaration the deletion pass fails to recognise is left +/// behind while the annotation is added, and the very next build fails with the +/// duplicate-hint error the goal exists to prevent -- so the parser has to +/// accept every form `java.util.Properties` does, not just `key=value`. +public class MigrateBuildHintsPropertyParsingTest { + + @Test + public void equalsSeparatorIsRecognized() { + assertEquals("codename1.arg.ios.teamId", + MigrateBuildHintsMojo.propertyKeyOf("codename1.arg.ios.teamId=ABCDE")); + } + + @Test + public void colonSeparatorIsRecognized() { + assertEquals("codename1.arg.ios.teamId", + MigrateBuildHintsMojo.propertyKeyOf("codename1.arg.ios.teamId:ABCDE")); + } + + /// The form that used to survive the deletion pass and break the next build. + @Test + public void whitespaceSeparatorIsRecognized() { + assertEquals("codename1.arg.ios.teamId", + MigrateBuildHintsMojo.propertyKeyOf("codename1.arg.ios.teamId ABCDE")); + assertEquals("codename1.arg.ios.teamId", + MigrateBuildHintsMojo.propertyKeyOf("codename1.arg.ios.teamId\tABCDE")); + } + + @Test + public void leadingWhitespaceIsIgnored() { + assertEquals("codename1.arg.ios.teamId", + MigrateBuildHintsMojo.propertyKeyOf(" codename1.arg.ios.teamId = ABCDE")); + } + + @Test + public void spacingAroundTheSeparatorIsIgnored() { + assertEquals("codename1.arg.ios.teamId", + MigrateBuildHintsMojo.propertyKeyOf("codename1.arg.ios.teamId = ABCDE")); + } + + /// A key may escape the characters that would otherwise end it. + @Test + public void escapedSeparatorsStayPartOfTheKey() { + assertEquals("a=b", MigrateBuildHintsMojo.propertyKeyOf("a\\=b=value")); + assertEquals("a b", MigrateBuildHintsMojo.propertyKeyOf("a\\ b=value")); + assertEquals("a:b", MigrateBuildHintsMojo.propertyKeyOf("a\\:b=value")); + } + + @Test + public void commentsAndBlanksDeclareNothing() { + assertNull(MigrateBuildHintsMojo.propertyKeyOf("# codename1.arg.ios.teamId=ABCDE")); + assertNull(MigrateBuildHintsMojo.propertyKeyOf("! codename1.arg.ios.teamId=ABCDE")); + assertNull(MigrateBuildHintsMojo.propertyKeyOf("")); + assertNull(MigrateBuildHintsMojo.propertyKeyOf(" ")); + } + + @Test + public void aValueOnlyLineHasNoSeparator() { + assertEquals("bare", MigrateBuildHintsMojo.propertyKeyOf("bare")); + } +} diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java index b9b8e0ba559..8ea6d65479e 100644 --- a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java @@ -235,6 +235,19 @@ public void aHintOnlyInThePropertiesFileIsFine() throws Exception { assertFalse(ctx.hasErrors()); } + /// A hint's deprecated alias names the same setting, so declaring the alias + /// in the properties file collides with the annotation just as the canonical + /// name would. Without this one value silently wins: AndroidGradleBuilder + /// reads `and.themeMode` and falls back to `cn1.androidTheme`. + @Test + public void aDeprecatedAliasOfAnAnnotatedHintIsAConflict() throws Exception { + Properties s = settings(); + s.setProperty("codename1.arg.cn1.androidTheme", "legacy"); + File classes = compile("@Android(themeMode = AndroidThemeMode.MODERN)"); + ProcessorContext ctx = run(classes, s, MAIN, false); + assertErrorContaining(ctx, "codename1.arg.cn1.androidTheme is declared twice"); + } + /// A commented-out line is not a declaration, and the archetype ships /// several. Properties.load skips them, so this is really a guard against /// anyone reintroducing a hand-rolled line scan. diff --git a/scripts/build_hint_miner.py b/scripts/build_hint_miner.py index 3f4699dac82..647a308e670 100644 --- a/scripts/build_hint_miner.py +++ b/scripts/build_hint_miner.py @@ -42,6 +42,10 @@ def read_literal(text, i): try: out.append(chr(int(text[i + 2:i + 6], 16))); i += 6; continue except ValueError: + # Not a well-formed \uXXXX after all. Fall through and treat + # the backslash as a plain escape rather than guessing at a + # code point; a malformed escape in a builder source is not + # this script's problem to diagnose. pass out.append(_ESCAPES.get(nxt, nxt)); i += 2; continue if c == '"': diff --git a/scripts/cn1playground/common/pom.xml b/scripts/cn1playground/common/pom.xml index d4ca37ab375..aa34a1fdd46 100644 --- a/scripts/cn1playground/common/pom.xml +++ b/scripts/cn1playground/common/pom.xml @@ -403,6 +403,7 @@ bytecode-compliance css + process-annotations diff --git a/scripts/gamebuilder/common/pom.xml b/scripts/gamebuilder/common/pom.xml index a07d212aad8..d22977aef1d 100644 --- a/scripts/gamebuilder/common/pom.xml +++ b/scripts/gamebuilder/common/pom.xml @@ -115,6 +115,7 @@ bytecode-compliance css + process-annotations diff --git a/scripts/gen-build-hint-annotations.sh b/scripts/gen-build-hint-annotations.sh index 27fb5ebb814..0ba5d0e386f 100755 --- a/scripts/gen-build-hint-annotations.sh +++ b/scripts/gen-build-hint-annotations.sh @@ -25,10 +25,12 @@ CATALOG_SRC="$CATALOG/src/main/java" check=0 [ "${1:-}" = "--check" ] && check=1 -if [ ! -f "$CLASSES/com/codename1/build/shared/BuildHintCodeGenerator.class" ]; then - echo "gen-build-hint-annotations: building the catalog" >&2 - (cd "$REPO_ROOT/maven" && mvn -q -B -pl build-hint-catalog package -DskipTests) -fi +# Always rebuild. Skipping when the class merely exists meant that editing a +# BuildHints*.java source and rerunning this script regenerated every view from +# the previous build's bytecode -- reporting success while silently ignoring the +# edit, and in --check mode passing a tree that is genuinely out of date. +echo "gen-build-hint-annotations: building the catalog" >&2 +(cd "$REPO_ROOT/maven" && mvn -q -B -pl build-hint-catalog package -DskipTests) SKILL_REF="$REPO_ROOT/scripts/initializr/common/src/main/resources/skill/references/build-hints.md" JAVASE_SRC="$REPO_ROOT/Ports/JavaSE/src" diff --git a/scripts/input-validation-app/common/codenameone_settings.properties b/scripts/input-validation-app/common/codenameone_settings.properties index 8726b661aa6..4973a52e4a0 100644 --- a/scripts/input-validation-app/common/codenameone_settings.properties +++ b/scripts/input-validation-app/common/codenameone_settings.properties @@ -1,6 +1,9 @@ codename1.android.keystore= codename1.android.keystoreAlias= codename1.android.keystorePassword= +codename1.arg.android.useAndroidX=true +codename1.arg.ios.newStorageLocation=true +codename1.arg.ios.uiscene=true codename1.arg.java.version=17 codename1.cssTheme=false codename1.displayName=CN1InputValidation diff --git a/scripts/input-validation-app/common/src/main/java/com/codenameone/inputvalidation/InputValidationApp.java b/scripts/input-validation-app/common/src/main/java/com/codenameone/inputvalidation/InputValidationApp.java index b1a0e065416..f52515a4f2f 100644 --- a/scripts/input-validation-app/common/src/main/java/com/codenameone/inputvalidation/InputValidationApp.java +++ b/scripts/input-validation-app/common/src/main/java/com/codenameone/inputvalidation/InputValidationApp.java @@ -1,38 +1,17 @@ /* - * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Codename One designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Codename One through http://www.codenameone.com/ if you - * need additional information or have any questions. */ package com.codenameone.inputvalidation; import com.codename1.system.Lifecycle; import com.codenameone.inputvalidation.gestures.GestureSuite; -import com.codename1.annotations.buildhints.*; /// Lifecycle entry point for the input-validation CN1 app. The whole app does /// one thing: it runs `GestureSuite` once and exits. No theme, no resources, /// no asset bundle -- by design, so a regression in input handling can never /// hide behind a missing texture, a slow startup, or a stale screenshot /// baseline. -@Android(useAndroidX = true) -@Ios(newStorageLocation = true, uiscene = true) public class InputValidationApp extends Lifecycle { @Override public void runApp() { diff --git a/scripts/video-builder/common/pom.xml b/scripts/video-builder/common/pom.xml index 5a9f0e5d5c8..54c1ef39659 100644 --- a/scripts/video-builder/common/pom.xml +++ b/scripts/video-builder/common/pom.xml @@ -38,7 +38,13 @@ compile-css process-classes - css + + css + + process-annotations + From 2803847f1dae4064dde12bb1283ccc0608f9921e Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 02:15:20 +0300 Subject: [PATCH 07/23] Do not migrate the guide's snippet project, and keep Settings from duplicating a hint docs/demos is the developer guide's snippet project: deliberately incomplete code fragments that illustrate @Entity, @Route, @AppIntent and @Mapped. Binding process-annotations there put those snippets in front of the other processors, which correctly rejected six of them, so the migration is reverted and its two hints are back in the properties file. That the project omitted the goal was the point, not an oversight. The other three newly bound projects were checked rather than assumed: gamebuilder, video-builder and cn1playground each run process-annotations cleanly and emit 6, 3 and 5 hints respectively. Settings could still create the duplicate the migration is careful to avoid. In a generated project ios.themeMode and its neighbours are annotations, but the Build Hints UI decides a hint is inactive from the properties file alone and its Add button writes a property -- producing a second declaration that fails the next build. The tool now reads META-INF/codenameone/build-hints.properties, the file the processor writes on every build and deletes when the last annotation goes, and renders those hints read-only with the attribute that owns them: "Set by @Ios(themeMode) on the main class." An unbuilt project has no such file and behaves as before. Also fixes the SpotBugs finding this branch introduced: `backslashes % 2 == 1` in the continuation scan is false for negative odd numbers, so it is `!= 0`. The count cannot go negative, but the idiom is wrong regardless of that. Co-Authored-By: Claude Opus 5 (1M context) --- .../common/codenameone_settings.properties | 1 + docs/demos/common/pom.xml | 1 - .../codenameone/developerguide/DemoCode.java | 24 - .../maven/MigrateBuildHintsMojo.java | 2 +- .../main/java/bsh/cn1/GeneratedCN1Access.java | 1437 ++++++--- ...neratedAccess_com_codename1_ai_vision.java | 2756 ++++++++++++++++- ...ratedAccess_com_codename1_annotations.java | 254 +- ..._com_codename1_annotations_buildhints.java | 1153 +++++++ .../GeneratedAccess_com_codename1_crash.java | 6 + .../gen/GeneratedAccess_com_codename1_db.java | 12 + .../GeneratedAccess_com_codename1_home.java | 2561 +++++++++++++++ ...cess_com_codename1_home_commissioning.java | 665 ++++ ...eneratedAccess_com_codename1_home_spi.java | 580 ++++ ...GeneratedAccess_com_codename1_intents.java | 1168 +++++++ ...ratedAccess_com_codename1_intents_spi.java | 446 +++ ...eneratedAccess_com_codename1_security.java | 95 +- ...cess_com_codename1_security_hardening.java | 394 +++ ...dAccess_com_codename1_security_shield.java | 1 + ...eneratedAccess_com_codename1_surfaces.java | 6 + .../gen/GeneratedAccess_com_codename1_ui.java | 153 + ...neratedAccess_com_codename1_ui_editor.java | 66 + .../GeneratedAccess_com_codename1_util.java | 15 + ...eneratedAccess_com_codename1_wearable.java | 95 +- .../bsh/cn1/gen/GeneratedAccess_java_io.java | 4 + .../settings/CodenameOneSettings.java | 72 +- .../settings/BuildHintCatalogTest.java | 21 + 26 files changed, 11306 insertions(+), 682 deletions(-) create mode 100644 scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_annotations_buildhints.java create mode 100644 scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home.java create mode 100644 scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home_commissioning.java create mode 100644 scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home_spi.java create mode 100644 scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_intents.java create mode 100644 scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_intents_spi.java create mode 100644 scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security_hardening.java diff --git a/docs/demos/common/codenameone_settings.properties b/docs/demos/common/codenameone_settings.properties index f096134cbe8..8494fded9dd 100644 --- a/docs/demos/common/codenameone_settings.properties +++ b/docs/demos/common/codenameone_settings.properties @@ -1,6 +1,7 @@ codename1.android.keystore= codename1.android.keystoreAlias= codename1.android.keystorePassword= +codename1.arg.ios.newStorageLocation=true codename1.arg.java.version=17 codename1.displayName=DemoCode codename1.icon=icon.png diff --git a/docs/demos/common/pom.xml b/docs/demos/common/pom.xml index 3f1b32b5884..40104bae6ec 100644 --- a/docs/demos/common/pom.xml +++ b/docs/demos/common/pom.xml @@ -350,7 +350,6 @@ compliance-check css - process-annotations diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java index 02cb53f3755..759bde784ab 100644 --- a/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java +++ b/docs/demos/common/src/main/java/com/codenameone/developerguide/DemoCode.java @@ -1,34 +1,10 @@ -/* - * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Codename One designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Codename One through http://www.codenameone.com/ if you - * need additional information or have any questions. - */ package com.codenameone.developerguide; import com.codename1.system.Lifecycle; -import com.codename1.annotations.buildhints.*; /** * Application entry point that launches the demo browser. */ -@Ios(newStorageLocation = true) public class DemoCode extends Lifecycle { @Override public void runApp() { diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index 6ecc9fc579a..e1ea5a01430 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -560,7 +560,7 @@ private static boolean continues(String line) { for (int i = line.length() - 1; i >= 0 && line.charAt(i) == '\\'; i--) { backslashes++; } - return backslashes % 2 == 1; + return backslashes % 2 != 0; } /** diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/GeneratedCN1Access.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/GeneratedCN1Access.java index b201e255758..754b57a9faa 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/GeneratedCN1Access.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/GeneratedCN1Access.java @@ -35,6 +35,7 @@ import bsh.cn1.gen.GeneratedAccess_com_codename1_ai_vision; import bsh.cn1.gen.GeneratedAccess_com_codename1_analytics; import bsh.cn1.gen.GeneratedAccess_com_codename1_annotations; +import bsh.cn1.gen.GeneratedAccess_com_codename1_annotations_buildhints; import bsh.cn1.gen.GeneratedAccess_com_codename1_annotations_graphql; import bsh.cn1.gen.GeneratedAccess_com_codename1_annotations_grpc; import bsh.cn1.gen.GeneratedAccess_com_codename1_annotations_rest; @@ -88,6 +89,11 @@ import bsh.cn1.gen.GeneratedAccess_com_codename1_health_nutrition; import bsh.cn1.gen.GeneratedAccess_com_codename1_health_sensors; import bsh.cn1.gen.GeneratedAccess_com_codename1_health_workout; +import bsh.cn1.gen.GeneratedAccess_com_codename1_home; +import bsh.cn1.gen.GeneratedAccess_com_codename1_home_commissioning; +import bsh.cn1.gen.GeneratedAccess_com_codename1_home_spi; +import bsh.cn1.gen.GeneratedAccess_com_codename1_intents; +import bsh.cn1.gen.GeneratedAccess_com_codename1_intents_spi; import bsh.cn1.gen.GeneratedAccess_com_codename1_io; import bsh.cn1.gen.GeneratedAccess_com_codename1_io_bonjour; import bsh.cn1.gen.GeneratedAccess_com_codename1_io_graphql; @@ -125,6 +131,7 @@ import bsh.cn1.gen.GeneratedAccess_com_codename1_push; import bsh.cn1.gen.GeneratedAccess_com_codename1_router; import bsh.cn1.gen.GeneratedAccess_com_codename1_security; +import bsh.cn1.gen.GeneratedAccess_com_codename1_security_hardening; import bsh.cn1.gen.GeneratedAccess_com_codename1_security_shield; import bsh.cn1.gen.GeneratedAccess_com_codename1_security_shield_spi; import bsh.cn1.gen.GeneratedAccess_com_codename1_sensors; @@ -264,24 +271,31 @@ public final class GeneratedCN1Access implements CN1Access { "com.codename1.ai.language.Translator", "com.codename1.ai.language.Translator.Session", "com.codename1.ai.vision.Barcode", + "com.codename1.ai.vision.BarcodeFormat", "com.codename1.ai.vision.BarcodeScanner", + "com.codename1.ai.vision.CodeScanner", + "com.codename1.ai.vision.CodeScannerOptions", "com.codename1.ai.vision.DocumentScanResult", "com.codename1.ai.vision.DocumentScanner", "com.codename1.ai.vision.Face", "com.codename1.ai.vision.FaceDetector", + "com.codename1.ai.vision.FaceLandmarks", "com.codename1.ai.vision.ImageLabel", "com.codename1.ai.vision.ImageLabeler", "com.codename1.ai.vision.Pose", "com.codename1.ai.vision.Pose.Landmark", "com.codename1.ai.vision.PoseDetector", + "com.codename1.ai.vision.PoseLandmarks", "com.codename1.ai.vision.SegmentationMask", "com.codename1.ai.vision.SelfieSegmenter", "com.codename1.ai.vision.TextRecognitionResult", "com.codename1.ai.vision.TextRecognitionResult.TextBlock", "com.codename1.ai.vision.TextRecognizer", + "com.codename1.ai.vision.TextScript", "com.codename1.ai.vision.VisionAnalyzer", "com.codename1.ai.vision.VisionBackend", "com.codename1.ai.vision.VisionBackends", + "com.codename1.ai.vision.VisionCameraView", "com.codename1.ai.vision.VisionException", "com.codename1.ai.vision.VisionFeature", "com.codename1.ai.vision.VisionImage", @@ -311,6 +325,7 @@ public final class GeneratedCN1Access implements CN1Access { "com.codename1.analytics.LegacyAnalyticsProviderAdapter", "com.codename1.analytics.LoggingAnalyticsProvider", "com.codename1.analytics.MatomoAnalyticsProvider", + "com.codename1.annotations.AppIntent", "com.codename1.annotations.Async", "com.codename1.annotations.Async.Execute", "com.codename1.annotations.Async.Schedule", @@ -323,9 +338,17 @@ public final class GeneratedCN1Access implements CN1Access { "com.codename1.annotations.DisableNullChecksAndArrayBoundsChecks", "com.codename1.annotations.Email", "com.codename1.annotations.Entity", + "com.codename1.annotations.EntityId", + "com.codename1.annotations.EntityImage", + "com.codename1.annotations.EntityQuery", + "com.codename1.annotations.EntityQuery.Kind", + "com.codename1.annotations.EntitySubtitle", + "com.codename1.annotations.EntityTitle", "com.codename1.annotations.ExistIn", "com.codename1.annotations.Fused", "com.codename1.annotations.Id", + "com.codename1.annotations.IntentEntity", + "com.codename1.annotations.IntentParam", "com.codename1.annotations.JsonIgnore", "com.codename1.annotations.JsonProperty", "com.codename1.annotations.Length", @@ -342,6 +365,23 @@ public final class GeneratedCN1Access implements CN1Access { "com.codename1.annotations.XmlElement", "com.codename1.annotations.XmlRoot", "com.codename1.annotations.XmlTransient", + "com.codename1.annotations.buildhints.Android", + "com.codename1.annotations.buildhints.AndroidThemeMode", + "com.codename1.annotations.buildhints.Build", + "com.codename1.annotations.buildhints.Desktop", + "com.codename1.annotations.buildhints.DesktopTitleBar", + "com.codename1.annotations.buildhints.HardenControlFlow", + "com.codename1.annotations.buildhints.HardenLevel", + "com.codename1.annotations.buildhints.HardenStrings", + "com.codename1.annotations.buildhints.Hardening", + "com.codename1.annotations.buildhints.InstallLocation", + "com.codename1.annotations.buildhints.Ios", + "com.codename1.annotations.buildhints.IosDependencyManager", + "com.codename1.annotations.buildhints.IosPrivacy", + "com.codename1.annotations.buildhints.IosProjectType", + "com.codename1.annotations.buildhints.IosThemeMode", + "com.codename1.annotations.buildhints.NativeThemeMode", + "com.codename1.annotations.buildhints.OnDeviceDebug", "com.codename1.annotations.graphql.GraphQLClient", "com.codename1.annotations.graphql.Mutation", "com.codename1.annotations.graphql.Query", @@ -671,7 +711,10 @@ public final class GeneratedCN1Access implements CN1Access { "com.codename1.crash.CrashProtection", "com.codename1.crash.PiiScrubber", "com.codename1.db.Cursor", + "com.codename1.db.CursorExt", "com.codename1.db.Database", + "com.codename1.db.DatabaseConfig", + "com.codename1.db.DatabaseEncryptionException", "com.codename1.db.Row", "com.codename1.db.RowExt", "com.codename1.db.ThreadSafeDatabase", @@ -961,6 +1004,70 @@ public final class GeneratedCN1Access implements CN1Access { "com.codename1.health.workout.WorkoutSession", "com.codename1.health.workout.WorkoutSessionListener", "com.codename1.health.workout.WorkoutSessionState", + "com.codename1.home.Accessory", + "com.codename1.home.AccessoryCategory", + "com.codename1.home.AccessoryService", + "com.codename1.home.AirQualityLevel", + "com.codename1.home.AlarmState", + "com.codename1.home.ChargingState", + "com.codename1.home.DoorState", + "com.codename1.home.FanMode", + "com.codename1.home.HeatingCoolingMode", + "com.codename1.home.HomeAuthorizationStatus", + "com.codename1.home.HomeAvailability", + "com.codename1.home.HomeBackend", + "com.codename1.home.HomeChangeListener", + "com.codename1.home.HomeConfigurationException", + "com.codename1.home.HomeError", + "com.codename1.home.HomeException", + "com.codename1.home.HomeRoom", + "com.codename1.home.HomeStructure", + "com.codename1.home.HomeStructureEvent", + "com.codename1.home.HomeStructureListener", + "com.codename1.home.HomeZone", + "com.codename1.home.LockState", + "com.codename1.home.PositionState", + "com.codename1.home.Scene", + "com.codename1.home.SceneAction", + "com.codename1.home.SceneType", + "com.codename1.home.ServiceType", + "com.codename1.home.SmartHome", + "com.codename1.home.StructureChangeKind", + "com.codename1.home.SubscriptionRequest", + "com.codename1.home.Trait", + "com.codename1.home.TraitChangeBatch", + "com.codename1.home.TraitConstraint", + "com.codename1.home.TraitReadRequest", + "com.codename1.home.TraitReading", + "com.codename1.home.TraitSubscription", + "com.codename1.home.TraitUnit", + "com.codename1.home.TraitUnitDimension", + "com.codename1.home.TraitValue", + "com.codename1.home.TraitValueKind", + "com.codename1.home.TraitWrite", + "com.codename1.home.TraitWriteResult", + "com.codename1.home.commissioning.Commissioner", + "com.codename1.home.commissioning.CommissioningRequest", + "com.codename1.home.commissioning.CommissioningResult", + "com.codename1.home.commissioning.CommissioningStyle", + "com.codename1.home.commissioning.SetupPayload", + "com.codename1.home.spi.HomeBridge", + "com.codename1.intents.AppEntity", + "com.codename1.intents.DynamicIntent", + "com.codename1.intents.EntitySelectionHandler", + "com.codename1.intents.Exposure", + "com.codename1.intents.IntentCompletion", + "com.codename1.intents.IntentContext", + "com.codename1.intents.IntentDates", + "com.codename1.intents.IntentDeclaration", + "com.codename1.intents.IntentDispatcher", + "com.codename1.intents.IntentParameterInfo", + "com.codename1.intents.IntentParameterType", + "com.codename1.intents.IntentResult", + "com.codename1.intents.IntentSerializer", + "com.codename1.intents.IntentSource", + "com.codename1.intents.Intents", + "com.codename1.intents.spi.IntentBridge", "com.codename1.io.AccessToken", "com.codename1.io.BufferedInputStream", "com.codename1.io.BufferedOutputStream", @@ -1361,6 +1468,8 @@ public final class GeneratedCN1Access implements CN1Access { "com.codename1.security.SecureRandom", "com.codename1.security.SecureStorage", "com.codename1.security.Signature", + "com.codename1.security.TapjackingPolicy", + "com.codename1.security.hardening.Hardening", "com.codename1.security.shield.AppShield", "com.codename1.security.shield.FailureMode", "com.codename1.security.shield.HostPolicy", @@ -1820,6 +1929,7 @@ public final class GeneratedCN1Access implements CN1Access { "com.codename1.vr.VRSettings", "com.codename1.vr.VRView", "com.codename1.wearable.WearableConnection", + "com.codename1.wearable.WearableConnection.DroppedDeliveryHandler", "com.codename1.wearable.WearableDataListener", "com.codename1.wearable.WearableMessage", "com.codename1.wearable.WearableMessageListener", @@ -2072,6 +2182,8 @@ private static Map buildMethodIndex() { fillMethodIndex26(index); fillMethodIndex27(index); fillMethodIndex28(index); + fillMethodIndex29(index); + fillMethodIndex30(index); return index; } @@ -2157,24 +2269,31 @@ private static void fillMethodIndex1(Map index) { index.put("com.codename1.ai.language.Translator", splitMembers("")); index.put("com.codename1.ai.language.Translator.Session", splitMembers("")); index.put("com.codename1.ai.vision.Barcode", splitMembers("")); + index.put("com.codename1.ai.vision.BarcodeFormat", splitMembers("")); index.put("com.codename1.ai.vision.BarcodeScanner", splitMembers("")); + index.put("com.codename1.ai.vision.CodeScanner", splitMembers("")); + index.put("com.codename1.ai.vision.CodeScannerOptions", splitMembers("")); index.put("com.codename1.ai.vision.DocumentScanResult", splitMembers("")); index.put("com.codename1.ai.vision.DocumentScanner", splitMembers("")); index.put("com.codename1.ai.vision.Face", splitMembers("")); index.put("com.codename1.ai.vision.FaceDetector", splitMembers("")); + index.put("com.codename1.ai.vision.FaceLandmarks", splitMembers("")); index.put("com.codename1.ai.vision.ImageLabel", splitMembers("")); index.put("com.codename1.ai.vision.ImageLabeler", splitMembers("")); index.put("com.codename1.ai.vision.Pose", splitMembers("")); index.put("com.codename1.ai.vision.Pose.Landmark", splitMembers("")); index.put("com.codename1.ai.vision.PoseDetector", splitMembers("")); + index.put("com.codename1.ai.vision.PoseLandmarks", splitMembers("")); index.put("com.codename1.ai.vision.SegmentationMask", splitMembers("")); index.put("com.codename1.ai.vision.SelfieSegmenter", splitMembers("")); index.put("com.codename1.ai.vision.TextRecognitionResult", splitMembers("")); index.put("com.codename1.ai.vision.TextRecognitionResult.TextBlock", splitMembers("")); index.put("com.codename1.ai.vision.TextRecognizer", splitMembers("")); + index.put("com.codename1.ai.vision.TextScript", splitMembers("")); index.put("com.codename1.ai.vision.VisionAnalyzer", splitMembers("")); index.put("com.codename1.ai.vision.VisionBackend", splitMembers("")); index.put("com.codename1.ai.vision.VisionBackends", splitMembers("")); + index.put("com.codename1.ai.vision.VisionCameraView", splitMembers("")); index.put("com.codename1.ai.vision.VisionException", splitMembers("")); index.put("com.codename1.ai.vision.VisionFeature", splitMembers("")); index.put("com.codename1.ai.vision.VisionImage", splitMembers("")); @@ -2200,16 +2319,17 @@ private static void fillMethodIndex1(Map index) { index.put("com.codename1.analytics.ConsentMode", splitMembers("")); index.put("com.codename1.analytics.FirebaseAnalyticsProvider", splitMembers("")); index.put("com.codename1.analytics.FirebaseAnalyticsProvider.Bridge", splitMembers("")); + } + + private static void fillMethodIndex2(Map index) { index.put("com.codename1.analytics.GoogleAnalyticsProvider", splitMembers("")); index.put("com.codename1.analytics.LegacyAnalyticsProviderAdapter", splitMembers("")); index.put("com.codename1.analytics.LoggingAnalyticsProvider", splitMembers("")); index.put("com.codename1.analytics.MatomoAnalyticsProvider", splitMembers("")); + index.put("com.codename1.annotations.AppIntent", splitMembers("")); index.put("com.codename1.annotations.Async", splitMembers("")); index.put("com.codename1.annotations.Async.Execute", splitMembers("")); index.put("com.codename1.annotations.Async.Schedule", splitMembers("")); - } - - private static void fillMethodIndex2(Map index) { index.put("com.codename1.annotations.Bind", splitMembers("")); index.put("com.codename1.annotations.Bindable", splitMembers("")); index.put("com.codename1.annotations.Column", splitMembers("")); @@ -2219,9 +2339,17 @@ private static void fillMethodIndex2(Map index) { index.put("com.codename1.annotations.DisableNullChecksAndArrayBoundsChecks", splitMembers("")); index.put("com.codename1.annotations.Email", splitMembers("")); index.put("com.codename1.annotations.Entity", splitMembers("")); + index.put("com.codename1.annotations.EntityId", splitMembers("")); + index.put("com.codename1.annotations.EntityImage", splitMembers("")); + index.put("com.codename1.annotations.EntityQuery", splitMembers("")); + index.put("com.codename1.annotations.EntityQuery.Kind", splitMembers("")); + index.put("com.codename1.annotations.EntitySubtitle", splitMembers("")); + index.put("com.codename1.annotations.EntityTitle", splitMembers("")); index.put("com.codename1.annotations.ExistIn", splitMembers("")); index.put("com.codename1.annotations.Fused", splitMembers("")); index.put("com.codename1.annotations.Id", splitMembers("")); + index.put("com.codename1.annotations.IntentEntity", splitMembers("")); + index.put("com.codename1.annotations.IntentParam", splitMembers("")); index.put("com.codename1.annotations.JsonIgnore", splitMembers("")); index.put("com.codename1.annotations.JsonProperty", splitMembers("")); index.put("com.codename1.annotations.Length", splitMembers("")); @@ -2238,9 +2366,29 @@ private static void fillMethodIndex2(Map index) { index.put("com.codename1.annotations.XmlElement", splitMembers("")); index.put("com.codename1.annotations.XmlRoot", splitMembers("")); index.put("com.codename1.annotations.XmlTransient", splitMembers("")); + index.put("com.codename1.annotations.buildhints.Android", splitMembers("")); + index.put("com.codename1.annotations.buildhints.AndroidThemeMode", splitMembers("")); + index.put("com.codename1.annotations.buildhints.Build", splitMembers("")); + index.put("com.codename1.annotations.buildhints.Desktop", splitMembers("")); + index.put("com.codename1.annotations.buildhints.DesktopTitleBar", splitMembers("")); + index.put("com.codename1.annotations.buildhints.HardenControlFlow", splitMembers("")); + index.put("com.codename1.annotations.buildhints.HardenLevel", splitMembers("")); + index.put("com.codename1.annotations.buildhints.HardenStrings", splitMembers("")); + index.put("com.codename1.annotations.buildhints.Hardening", splitMembers("")); + index.put("com.codename1.annotations.buildhints.InstallLocation", splitMembers("")); + index.put("com.codename1.annotations.buildhints.Ios", splitMembers("")); + index.put("com.codename1.annotations.buildhints.IosDependencyManager", splitMembers("")); + index.put("com.codename1.annotations.buildhints.IosPrivacy", splitMembers("")); + index.put("com.codename1.annotations.buildhints.IosProjectType", splitMembers("")); + index.put("com.codename1.annotations.buildhints.IosThemeMode", splitMembers("")); + index.put("com.codename1.annotations.buildhints.NativeThemeMode", splitMembers("")); + index.put("com.codename1.annotations.buildhints.OnDeviceDebug", splitMembers("")); index.put("com.codename1.annotations.graphql.GraphQLClient", splitMembers("")); index.put("com.codename1.annotations.graphql.Mutation", splitMembers("")); index.put("com.codename1.annotations.graphql.Query", splitMembers("")); + } + + private static void fillMethodIndex3(Map index) { index.put("com.codename1.annotations.graphql.Subscription", splitMembers("")); index.put("com.codename1.annotations.graphql.Var", splitMembers("")); index.put("com.codename1.annotations.grpc.GrpcClient", splitMembers("")); @@ -2274,9 +2422,6 @@ private static void fillMethodIndex2(Map index) { index.put("com.codename1.ar.ARHitResult.Type", splitMembers("")); index.put("com.codename1.ar.ARImageAnchor", splitMembers("")); index.put("com.codename1.ar.ARLightEstimate", splitMembers("")); - } - - private static void fillMethodIndex3(Map index) { index.put("com.codename1.ar.ARModel", splitMembers("")); index.put("com.codename1.ar.ARNode", splitMembers("")); index.put("com.codename1.ar.ARPlane", splitMembers("")); @@ -2308,6 +2453,9 @@ private static void fillMethodIndex3(Map index) { index.put("com.codename1.binding.Binding", splitMembers("")); index.put("com.codename1.binding.NotifiableBinding", splitMembers("")); index.put("com.codename1.bluetooth.AdapterState", splitMembers("")); + } + + private static void fillMethodIndex4(Map index) { index.put("com.codename1.bluetooth.AdapterStateListener", splitMembers("")); index.put("com.codename1.bluetooth.Bluetooth", splitMembers("")); index.put("com.codename1.bluetooth.BluetoothDevice", splitMembers("")); @@ -2341,9 +2489,6 @@ private static void fillMethodIndex3(Map index) { index.put("com.codename1.bluetooth.le.L2capServer", splitMembers("")); index.put("com.codename1.bluetooth.le.ScanFilter", splitMembers("")); index.put("com.codename1.bluetooth.le.ScanListener", splitMembers("")); - } - - private static void fillMethodIndex4(Map index) { index.put("com.codename1.bluetooth.le.ScanMode", splitMembers("")); index.put("com.codename1.bluetooth.le.ScanResult", splitMembers("")); index.put("com.codename1.bluetooth.le.ScanSettings", splitMembers("")); @@ -2375,6 +2520,9 @@ private static void fillMethodIndex4(Map index) { index.put("com.codename1.calendar.CalendarCache", splitMembers("")); index.put("com.codename1.calendar.CalendarCapabilities", splitMembers("")); index.put("com.codename1.calendar.CalendarCapability", splitMembers("")); + } + + private static void fillMethodIndex5(Map index) { index.put("com.codename1.calendar.CalendarChange", splitMembers("")); index.put("com.codename1.calendar.CalendarChange.ChangeType", splitMembers("")); index.put("com.codename1.calendar.CalendarChange.EntityType", splitMembers("")); @@ -2408,9 +2556,6 @@ private static void fillMethodIndex4(Map index) { index.put("com.codename1.calendar.CalendarTokenProvider", splitMembers("")); index.put("com.codename1.calendar.DefaultCalendarHttpTransport", splitMembers("")); index.put("com.codename1.calendar.FreeBusyInterval", splitMembers("")); - } - - private static void fillMethodIndex5(Map index) { index.put("com.codename1.calendar.GoogleCalendarSource", splitMembers("")); index.put("com.codename1.calendar.ICalendarCodec", splitMembers("")); index.put("com.codename1.calendar.LocalCalendarSource", splitMembers("")); @@ -2442,6 +2587,9 @@ private static void fillMethodIndex5(Map index) { index.put("com.codename1.car.CarActionListener", splitMembers("")); index.put("com.codename1.car.CarActionStrip", splitMembers("")); index.put("com.codename1.car.CarApplication", splitMembers("")); + } + + private static void fillMethodIndex6(Map index) { index.put("com.codename1.car.CarColor", splitMembers("")); index.put("com.codename1.car.CarConnectionListener", splitMembers("")); index.put("com.codename1.car.CarContext", splitMembers("")); @@ -2475,9 +2623,6 @@ private static void fillMethodIndex5(Map index) { index.put("com.codename1.charts.models.Point", splitMembers("")); index.put("com.codename1.charts.models.RangeCategorySeries", splitMembers("")); index.put("com.codename1.charts.models.SeriesSelection", splitMembers("")); - } - - private static void fillMethodIndex6(Map index) { index.put("com.codename1.charts.models.TimeSeries", splitMembers("")); index.put("com.codename1.charts.models.XYMultipleSeriesDataset", splitMembers("")); index.put("com.codename1.charts.models.XYSeries", splitMembers("")); @@ -2509,6 +2654,9 @@ private static void fillMethodIndex6(Map index) { index.put("com.codename1.charts.views.CubicLineChart", splitMembers("")); index.put("com.codename1.charts.views.DialChart", splitMembers("")); index.put("com.codename1.charts.views.DoughnutChart", splitMembers("")); + } + + private static void fillMethodIndex7(Map index) { index.put("com.codename1.charts.views.LineChart", splitMembers("")); index.put("com.codename1.charts.views.PieChart", splitMembers("")); index.put("com.codename1.charts.views.PieMapper", splitMembers("")); @@ -2542,9 +2690,6 @@ private static void fillMethodIndex6(Map index) { index.put("com.codename1.components.FileTreeModel", splitMembers("addExtensionFilter(String)getChildren(Object)isLeaf(Object)")); index.put("com.codename1.components.FloatingActionButton", splitMembers("accessibilityChanged()accessibilityChanged(int)addActionListener(ActionListener)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)bindFabToContainer(Component)bindFabToContainer(Component, int, int)bindProperty(String, BindTarget)bindStateTo(Button)blocksSideSwipe()clearClientProperties()contains(int, int)containsOrOwns(int, int)createStyleAnimation(String, int)createSubFAB(char, String)drop(Component, int, int)getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getActionListeners()getAlignment()getAllStyles()getAnimationManager()getBadgeStyleComponent()getBadgeText()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getCommand()getComponentForm()getComponentState()getCursor()getDirtyRegion()getDisabledIcon()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getFloatingActionTextUIID()getFontIcon()getFontIconSize()getGap()getHeight()getIcon()getIconFont()getIconFromState()getIconStyleComponent()getIconUIID()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getListeners()getMask()getMaskName()getMaskedIcon()getMaterialIcon()getMaterialIconSize()getMaxAutoSize()getMinAutoSize()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedIcon()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getReleaseRadius()getRolloverIcon()getRolloverPressedIcon()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getShiftMillimeters()getShiftMillimetersF()getShiftText()getSideGap()getState()getStringWidth(Font)getStyle()getTabIndex()getTensileLength()getText()getTextPosition()getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVerticalAlignment()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()isAlwaysTensile()isAutoRelease()isAutoSizeMode()isBlockLead()isCapsText()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isEndsWith3Points()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isLegacyRenderer()isOpaque()isOppositeSide()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSelected()isShouldLocalize()isShowEvenIfBlank()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTextSelectionEnabled()isTickerEnabled()isTickerRunning()isToggle()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])pressed()putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)released()released(int, int)remove()removeActionListener(ActionListener)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlignment(int)setAlwaysTensile(boolean)setAutoRelease(boolean)setAutoSizeMode(boolean)setBadgeText(String)setBadgeUIID(String)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCapsText(boolean)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setCommand(Command)setComponentState(Object)setCursor(int)setDirtyRegion(Rectangle)setDisabledIcon(Image)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditingDelegate(Editable)setEnabled(boolean)setEndsWith3Points(boolean)setFlatten(boolean)setFloatingActionTextUIID(String)setFocus(boolean)setFocusable(boolean)setFontIcon(char)setFontIcon(Font, char)setFontIcon(Font, char, float)setGap(int)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIcon(Image)setIconUIID(String)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLegacyRenderer(boolean)setMask(Object)setMaskName(String)setMaterialIcon(char)setMaterialIcon(char, float)setMaxAutoSize(float)setMinAutoSize(float)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedIcon(Image)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setReleaseRadius(int)setReleased()setRippleEffect(boolean)setRolloverIcon(Image)setRolloverPressedIcon(Image)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShiftMillimeters(float)setShiftMillimeters(int)setShiftText(int)setShouldCalcPreferredSize(boolean)setShouldLocalize(boolean)setShowEvenIfBlank(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTextPosition(int)setTextSelectionEnabled(boolean)setTickerEnabled(boolean)setToggle(boolean)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalAlignment(int)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)shouldTickerStart()startEditingAsync()startTicker()startTicker(long, boolean)stopEditing(Runnable)stopTicker()stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbind()unbindProperty(String, BindTarget)unbindStateFrom(Button)visibleBoundsContains(int, int)createBadge(String)createFAB(char)createFAB(char, String)getIconDefaultSize()isAutoSizing()setAutoSizing(boolean)setIconDefaultSize(float)")); index.put("com.codename1.components.FloatingHint", splitMembers("accessibilityChanged()accessibilityChanged(int)add(Component)add(Image)add(String)add(Object, Component)add(Object, String)add(Object, Image)addAll(Component[]...)addComponent(Component)addComponent(int, Component)addComponent(int, Object, Component)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animateHierarchy(int)animateHierarchyAndWait(int)animateHierarchyFade(int, int)animateHierarchyFadeAndWait(int, int)animateLayout(int)animateLayoutAndWait(int)animateLayoutFade(int, int)animateLayoutFadeAndWait(int, int)animateUnlayout(int, int, Runnable)animateUnlayoutAndWait(int, int)announceForAccessibility(String)applyRTL(boolean)bindProperty(String, BindTarget)blocksSideSwipe()clearClientProperties()contains(Component)contains(int, int)containsOrOwns(int, int)createAnimateHierarchy(int)createAnimateHierarchyFade(int, int)createAnimateLayout(int)createAnimateLayoutFade(int, int)createAnimateLayoutFadeAndWait(int, int)createAnimateUnlayout(int, int, Runnable)createReplaceTransition(Component, Component, Transition)createStyleAnimation(String, int)drop(Component, int, int)findDropTargetAt(int, int)findFirstFocusable()flushReplace()forceRevalidate()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getChildrenAsList(boolean)getClientProperty(String)getClosestComponentTo(int, int)getCloudBoundProperty()getCloudDestinationProperty()getComponentAt(int)getComponentAt(int, int)getComponentCount()getComponentForm()getComponentIndex(Component)getComponentState()getCursor()getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLayout()getLayoutHeight()getLayoutWidth()getLeadComponent()getLeadParent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getResponderAt(int, int)getSafeAreaRoot()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollIncrement()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()invalidate()isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isSafeArea()isSafeAreaRoot()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isSurface()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()iterator()iterator(boolean)keyPressed(int)keyReleased(int)keyRepeated(int)layoutContainer()longPointerPress(int, int)morph(Component, Component, int, Runnable)morphAndWait(Component, Component, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)remove()removeAll()removeComponent(Component)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replace(Component, Component, Transition)replace(Component, Component, Transition, Runnable, int)replaceAndWait(Component, Component, Transition)replaceAndWait(Component, Component, Transition, int)replaceAndWait(Component, Component, Transition, boolean)requestFocus()respondsToPointerEvents()revalidate()revalidateLater()revalidateWithAnimationSafety()scrollComponentToVisible(Component)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlwaysTensile(boolean)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLayout(Layout)setLeadComponent(Component)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setSafeArea(boolean)setSafeAreaRoot(boolean)setScrollAnimationSpeed(int)setScrollIncrement(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setScrollable(boolean)setScrollableX(boolean)setScrollableY(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUIManager(UIManager)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTabIndices(int)visibleBoundsContains(int, int)")); - } - - private static void fillMethodIndex7(Map index) { index.put("com.codename1.components.ImageViewer", splitMembers("accessibilityChanged()accessibilityChanged(int)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)bindProperty(String, BindTarget)blocksSideSwipe()clearClientProperties()contains(int, int)containsOrOwns(int, int)createStyleAnimation(String, int)deinitialize()drop(Component, int, int)getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getComponentForm()getComponentState()getCroppedImage(int)getCroppedImage(int, int, int)getCursor()getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getHeight()getImage()getImageList()getImageX()getImageY()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getSwipePlaceholder()getSwipeThreshold()getTabIndex()getTensileLength()getTextSelectionSupport()getThumbnailBarHeight()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()getZoom()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()initComponent()isAllowScaleDown()isAlwaysTensile()isAnimatedZoom()isBlockLead()isCellRenderer()isChildOf(Container)isCycleLeft()isCycleRight()isDraggable()isDropTarget()isEagerLock()isEditable()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isNavigationArrowsVisible()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isThumbnailsVisible()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)remove()removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAllowScaleDown(boolean)setAlwaysTensile(boolean)setAnimateZoom(boolean)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setCursor(int)setCycleLeft(boolean)setCycleRight(boolean)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEagerLock(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setImage(Image)setImageInitialPosition(int)setImageList(ListModel)setImageNoReposition(Image)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setName(String)setNavigationArrowsVisible(boolean)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setSwipePlaceholder(Image)setSwipeThreshold(float)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setThumbnailBarHeight(float)setThumbnailsVisible(boolean)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)setZoom(float)setZoom(float, float, float)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)visibleBoundsContains(int, int)")); index.put("com.codename1.components.InfiniteProgress", splitMembers("accessibilityChanged()accessibilityChanged(int)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animate(boolean)announceForAccessibility(String)bindProperty(String, BindTarget)blocksSideSwipe()clearClientProperties()contains(int, int)containsOrOwns(int, int)createStyleAnimation(String, int)drop(Component, int, int)getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAngleIncrease()getAnimation()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getComponentForm()getComponentState()getCursor()getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getMaterialDesignColor()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getTextSelectionSupport()getTickCount()getTintColor()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isMaterialDesignMode()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)remove()removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlwaysTensile(boolean)setAngleIncrease(int)setAnimation(Image)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setMaterialDesignColor(int)setMaterialDesignMode(boolean)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setTickCount(int)setTintColor(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)showInfiniteBlocking()showInifiniteBlocking()startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)visibleBoundsContains(int, int)getDefaultMaterialDesignColor()isDefaultMaterialDesignMode()setDefaultMaterialDesignColor(int)setDefaultMaterialDesignMode(boolean)")); index.put("com.codename1.components.InfiniteScrollAdapter", splitMembers("addMoreComponents(Component[], boolean)continueFetching()getComponentLimit()getInfiniteProgress()setComponentLimit(int)addMoreComponents(Container, Component[], boolean)continueFetching(Container)createInfiniteScroll(Container, Runnable)createInfiniteScroll(Container, Runnable, boolean)")); @@ -2576,13 +2721,19 @@ private static void fillMethodIndex7(Map index) { index.put("com.codename1.components.ToastBar", splitMembers("createStatus()getDefaultMessageUIID()getDefaultUIID()getPosition()setDefaultMessageUIID(String)setDefaultUIID(String)setPosition(int)setVisible(boolean)useFormLayeredPane(boolean)getDefaultMessageTimeout()getInstance()setDefaultMessageTimeout(int)showConnectionProgress(String, ConnectionRequest, SuccessCallback, FailureCallback)showErrorMessage(String)showErrorMessage(String, int)showInfoMessage(String)showMessage(String, char)showMessage(String, char, int)showMessage(String, char, ActionListener)showMessage(String, char, int, ActionListener)")); index.put("com.codename1.components.WebBrowser", splitMembers("accessibilityChanged()accessibilityChanged(int)add(Component)add(Image)add(String)add(Object, Component)add(Object, String)add(Object, Image)addAll(Component[]...)addComponent(Component)addComponent(int, Component)addComponent(int, Object, Component)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animateHierarchy(int)animateHierarchyAndWait(int)animateHierarchyFade(int, int)animateHierarchyFadeAndWait(int, int)animateLayout(int)animateLayoutAndWait(int)animateLayoutFade(int, int)animateLayoutFadeAndWait(int, int)animateUnlayout(int, int, Runnable)animateUnlayoutAndWait(int, int)announceForAccessibility(String)applyRTL(boolean)bindProperty(String, BindTarget)blocksSideSwipe()clearClientProperties()contains(Component)contains(int, int)containsOrOwns(int, int)createAnimateHierarchy(int)createAnimateHierarchyFade(int, int)createAnimateLayout(int)createAnimateLayoutFade(int, int)createAnimateLayoutFadeAndWait(int, int)createAnimateUnlayout(int, int, Runnable)createReplaceTransition(Component, Component, Transition)createStyleAnimation(String, int)destroy()drop(Component, int, int)findDropTargetAt(int, int)findFirstFocusable()flushReplace()forceRevalidate()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getBrowserNavigationCallback()getChildrenAsList(boolean)getClientProperty(String)getClosestComponentTo(int, int)getCloudBoundProperty()getCloudDestinationProperty()getComponentAt(int)getComponentAt(int, int)getComponentCount()getComponentForm()getComponentIndex(Component)getComponentState()getCursor()getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getInternal()getLabelForComponent()getLayout()getLayoutHeight()getLayoutWidth()getLeadComponent()getLeadParent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getPage()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getResponderAt(int, int)getSafeAreaRoot()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollIncrement()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getTextSelectionSupport()getTitle()getTooltip()getUIID()getUIManager()getURL()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()invalidate()isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isSafeArea()isSafeAreaRoot()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isSurface()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()iterator()iterator(boolean)keyPressed(int)keyReleased(int)keyRepeated(int)layoutContainer()longPointerPress(int, int)morph(Component, Component, int, Runnable)morphAndWait(Component, Component, int)onError(String, int)onLoad(String)onStart(String)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)reload()remove()removeAll()removeComponent(Component)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replace(Component, Component, Transition)replace(Component, Component, Transition, Runnable, int)replaceAndWait(Component, Component, Transition)replaceAndWait(Component, Component, Transition, int)replaceAndWait(Component, Component, Transition, boolean)requestFocus()respondsToPointerEvents()revalidate()revalidateLater()revalidateWithAnimationSafety()scrollComponentToVisible(Component)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlwaysTensile(boolean)setBlockLead(boolean)setBoundPropertyValue(String, Object)setBrowserNavigationCallback(BrowserNavigationCallback)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLayout(Layout)setLeadComponent(Component)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPage(String, String)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setSafeArea(boolean)setSafeAreaRoot(boolean)setScrollAnimationSpeed(int)setScrollIncrement(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setScrollable(boolean)setScrollableX(boolean)setScrollableY(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUIManager(UIManager)setURL(String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()stop()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTabIndices(int)visibleBoundsContains(int, int)createDataURI(byte[], String)")); index.put("com.codename1.contacts.Address", splitMembers("")); + } + + private static void fillMethodIndex8(Map index) { index.put("com.codename1.contacts.Contact", splitMembers("")); index.put("com.codename1.contacts.ContactsManager", splitMembers("")); index.put("com.codename1.contacts.ContactsModel", splitMembers("")); index.put("com.codename1.crash.CrashProtection", splitMembers("")); index.put("com.codename1.crash.PiiScrubber", splitMembers("")); index.put("com.codename1.db.Cursor", splitMembers("")); + index.put("com.codename1.db.CursorExt", splitMembers("")); index.put("com.codename1.db.Database", splitMembers("")); + index.put("com.codename1.db.DatabaseConfig", splitMembers("")); + index.put("com.codename1.db.DatabaseEncryptionException", splitMembers("")); index.put("com.codename1.db.Row", splitMembers("")); index.put("com.codename1.db.RowExt", splitMembers("")); index.put("com.codename1.db.ThreadSafeDatabase", splitMembers("")); @@ -2609,9 +2760,6 @@ private static void fillMethodIndex7(Map index) { index.put("com.codename1.gaming.VirtualButton", splitMembers("")); index.put("com.codename1.gaming.VirtualJoystick", splitMembers("")); index.put("com.codename1.gaming.VoiceListener", splitMembers("")); - } - - private static void fillMethodIndex8(Map index) { index.put("com.codename1.gaming.level.AssetCatalog", splitMembers("")); index.put("com.codename1.gaming.level.AssetDef", splitMembers("")); index.put("com.codename1.gaming.level.AssetDef.Kind", splitMembers("")); @@ -2640,6 +2788,9 @@ private static void fillMethodIndex8(Map index) { index.put("com.codename1.gaming.level.TileLayer", splitMembers("")); index.put("com.codename1.gaming.physics.BodyType", splitMembers("")); index.put("com.codename1.gaming.physics.ContactListener", splitMembers("")); + } + + private static void fillMethodIndex9(Map index) { index.put("com.codename1.gaming.physics.PhysicsBody", splitMembers("")); index.put("com.codename1.gaming.physics.PhysicsContact", splitMembers("")); index.put("com.codename1.gaming.physics.PhysicsJoint", splitMembers("")); @@ -2676,9 +2827,6 @@ private static void fillMethodIndex8(Map index) { index.put("com.codename1.gaming.physics.box2d.collision.TimeOfImpact.TOIOutput", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.collision.TimeOfImpact.TOIOutputState", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.collision.WorldManifold", splitMembers("")); - } - - private static void fillMethodIndex9(Map index) { index.put("com.codename1.gaming.physics.box2d.collision.broadphase.BroadPhase", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.collision.broadphase.BroadPhaseStrategy", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.collision.broadphase.DynamicTree", splitMembers("")); @@ -2707,6 +2855,9 @@ private static void fillMethodIndex9(Map index) { index.put("com.codename1.gaming.physics.box2d.common.Vec3", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.Body", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.BodyDef", splitMembers("")); + } + + private static void fillMethodIndex10(Map index) { index.put("com.codename1.gaming.physics.box2d.dynamics.BodyType", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.ContactManager", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.Filter", splitMembers("")); @@ -2743,9 +2894,6 @@ private static void fillMethodIndex9(Map index) { index.put("com.codename1.gaming.physics.box2d.dynamics.joints.FrictionJoint", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.joints.FrictionJointDef", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.joints.GearJoint", splitMembers("")); - } - - private static void fillMethodIndex10(Map index) { index.put("com.codename1.gaming.physics.box2d.dynamics.joints.GearJointDef", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.joints.Jacobian", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.joints.Joint", splitMembers("")); @@ -2774,6 +2922,9 @@ private static void fillMethodIndex10(Map index) { index.put("com.codename1.gaming.physics.box2d.pooling.arrays.IntArray", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.pooling.arrays.Vec2Array", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.pooling.normal.CircleStack", splitMembers("")); + } + + private static void fillMethodIndex11(Map index) { index.put("com.codename1.gaming.physics.box2d.pooling.normal.DefaultWorldPool", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.pooling.normal.MutableStack", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.pooling.normal.OrderedStack", splitMembers("")); @@ -2810,9 +2961,6 @@ private static void fillMethodIndex10(Map index) { index.put("com.codename1.health.AggregateResult", splitMembers("")); index.put("com.codename1.health.BloodPressureSample", splitMembers("")); index.put("com.codename1.health.CategorySample", splitMembers("")); - } - - private static void fillMethodIndex11(Map index) { index.put("com.codename1.health.Health", splitMembers("")); index.put("com.codename1.health.HealthAccess", splitMembers("")); index.put("com.codename1.health.HealthAggregationStyle", splitMembers("")); @@ -2841,6 +2989,9 @@ private static void fillMethodIndex11(Map index) { index.put("com.codename1.health.HealthUnitDimension", splitMembers("")); index.put("com.codename1.health.HealthWriteResult", splitMembers("")); index.put("com.codename1.health.QuantitySample", splitMembers("")); + } + + private static void fillMethodIndex12(Map index) { index.put("com.codename1.health.RecordingMethod", splitMembers("")); index.put("com.codename1.health.SamplePage", splitMembers("")); index.put("com.codename1.health.SampleQuery", splitMembers("")); @@ -2877,9 +3028,6 @@ private static void fillMethodIndex11(Map index) { index.put("com.codename1.health.sensors.TemperatureMeasurement", splitMembers("")); index.put("com.codename1.health.sensors.WeightMeasurement", splitMembers("")); index.put("com.codename1.health.workout.WorkoutConfiguration", splitMembers("")); - } - - private static void fillMethodIndex12(Map index) { index.put("com.codename1.health.workout.WorkoutEvent", splitMembers("")); index.put("com.codename1.health.workout.WorkoutEvent.Kind", splitMembers("")); index.put("com.codename1.health.workout.WorkoutLocationType", splitMembers("")); @@ -2887,6 +3035,73 @@ private static void fillMethodIndex12(Map index) { index.put("com.codename1.health.workout.WorkoutSession", splitMembers("")); index.put("com.codename1.health.workout.WorkoutSessionListener", splitMembers("")); index.put("com.codename1.health.workout.WorkoutSessionState", splitMembers("")); + index.put("com.codename1.home.Accessory", splitMembers("")); + index.put("com.codename1.home.AccessoryCategory", splitMembers("")); + index.put("com.codename1.home.AccessoryService", splitMembers("")); + index.put("com.codename1.home.AirQualityLevel", splitMembers("")); + index.put("com.codename1.home.AlarmState", splitMembers("")); + index.put("com.codename1.home.ChargingState", splitMembers("")); + index.put("com.codename1.home.DoorState", splitMembers("")); + index.put("com.codename1.home.FanMode", splitMembers("")); + index.put("com.codename1.home.HeatingCoolingMode", splitMembers("")); + index.put("com.codename1.home.HomeAuthorizationStatus", splitMembers("")); + index.put("com.codename1.home.HomeAvailability", splitMembers("")); + index.put("com.codename1.home.HomeBackend", splitMembers("")); + index.put("com.codename1.home.HomeChangeListener", splitMembers("")); + index.put("com.codename1.home.HomeConfigurationException", splitMembers("")); + index.put("com.codename1.home.HomeError", splitMembers("")); + index.put("com.codename1.home.HomeException", splitMembers("")); + index.put("com.codename1.home.HomeRoom", splitMembers("")); + index.put("com.codename1.home.HomeStructure", splitMembers("")); + index.put("com.codename1.home.HomeStructureEvent", splitMembers("")); + index.put("com.codename1.home.HomeStructureListener", splitMembers("")); + index.put("com.codename1.home.HomeZone", splitMembers("")); + } + + private static void fillMethodIndex13(Map index) { + index.put("com.codename1.home.LockState", splitMembers("")); + index.put("com.codename1.home.PositionState", splitMembers("")); + index.put("com.codename1.home.Scene", splitMembers("")); + index.put("com.codename1.home.SceneAction", splitMembers("")); + index.put("com.codename1.home.SceneType", splitMembers("")); + index.put("com.codename1.home.ServiceType", splitMembers("")); + index.put("com.codename1.home.SmartHome", splitMembers("")); + index.put("com.codename1.home.StructureChangeKind", splitMembers("")); + index.put("com.codename1.home.SubscriptionRequest", splitMembers("")); + index.put("com.codename1.home.Trait", splitMembers("")); + index.put("com.codename1.home.TraitChangeBatch", splitMembers("")); + index.put("com.codename1.home.TraitConstraint", splitMembers("")); + index.put("com.codename1.home.TraitReadRequest", splitMembers("")); + index.put("com.codename1.home.TraitReading", splitMembers("")); + index.put("com.codename1.home.TraitSubscription", splitMembers("")); + index.put("com.codename1.home.TraitUnit", splitMembers("")); + index.put("com.codename1.home.TraitUnitDimension", splitMembers("")); + index.put("com.codename1.home.TraitValue", splitMembers("")); + index.put("com.codename1.home.TraitValueKind", splitMembers("")); + index.put("com.codename1.home.TraitWrite", splitMembers("")); + index.put("com.codename1.home.TraitWriteResult", splitMembers("")); + index.put("com.codename1.home.commissioning.Commissioner", splitMembers("")); + index.put("com.codename1.home.commissioning.CommissioningRequest", splitMembers("")); + index.put("com.codename1.home.commissioning.CommissioningResult", splitMembers("")); + index.put("com.codename1.home.commissioning.CommissioningStyle", splitMembers("")); + index.put("com.codename1.home.commissioning.SetupPayload", splitMembers("")); + index.put("com.codename1.home.spi.HomeBridge", splitMembers("")); + index.put("com.codename1.intents.AppEntity", splitMembers("")); + index.put("com.codename1.intents.DynamicIntent", splitMembers("")); + index.put("com.codename1.intents.EntitySelectionHandler", splitMembers("")); + index.put("com.codename1.intents.Exposure", splitMembers("")); + index.put("com.codename1.intents.IntentCompletion", splitMembers("")); + index.put("com.codename1.intents.IntentContext", splitMembers("")); + index.put("com.codename1.intents.IntentDates", splitMembers("")); + index.put("com.codename1.intents.IntentDeclaration", splitMembers("")); + index.put("com.codename1.intents.IntentDispatcher", splitMembers("")); + index.put("com.codename1.intents.IntentParameterInfo", splitMembers("")); + index.put("com.codename1.intents.IntentParameterType", splitMembers("")); + index.put("com.codename1.intents.IntentResult", splitMembers("")); + index.put("com.codename1.intents.IntentSerializer", splitMembers("")); + index.put("com.codename1.intents.IntentSource", splitMembers("")); + index.put("com.codename1.intents.Intents", splitMembers("")); + index.put("com.codename1.intents.spi.IntentBridge", splitMembers("")); index.put("com.codename1.io.AccessToken", splitMembers("")); index.put("com.codename1.io.BufferedInputStream", splitMembers("")); index.put("com.codename1.io.BufferedOutputStream", splitMembers("")); @@ -2908,6 +3123,9 @@ private static void fillMethodIndex12(Map index) { index.put("com.codename1.io.JSONParser", splitMembers("")); index.put("com.codename1.io.JSONParser.RawJson", splitMembers("")); index.put("com.codename1.io.JSONWriter", splitMembers("")); + } + + private static void fillMethodIndex14(Map index) { index.put("com.codename1.io.JSONWriter.ArrayBuilder", splitMembers("")); index.put("com.codename1.io.JSONWriter.ObjectBuilder", splitMembers("")); index.put("com.codename1.io.Log", splitMembers("")); @@ -2944,9 +3162,6 @@ private static void fillMethodIndex12(Map index) { index.put("com.codename1.io.bonjour.BonjourService", splitMembers("")); index.put("com.codename1.io.bonjour.BonjourServiceListener", splitMembers("")); index.put("com.codename1.io.graphql.GraphQL", splitMembers("")); - } - - private static void fillMethodIndex13(Map index) { index.put("com.codename1.io.graphql.GraphQLClients", splitMembers("")); index.put("com.codename1.io.graphql.GraphQLClients.Factory", splitMembers("")); index.put("com.codename1.io.graphql.GraphQLError", splitMembers("")); @@ -2975,6 +3190,9 @@ private static void fillMethodIndex13(Map index) { index.put("com.codename1.io.gzip.GZIPHeader", splitMembers("")); index.put("com.codename1.io.gzip.GZIPInputStream", splitMembers("")); index.put("com.codename1.io.gzip.GZIPOutputStream", splitMembers("")); + } + + private static void fillMethodIndex15(Map index) { index.put("com.codename1.io.gzip.Inflater", splitMembers("")); index.put("com.codename1.io.gzip.InflaterInputStream", splitMembers("")); index.put("com.codename1.io.gzip.JZlib", splitMembers("")); @@ -3011,9 +3229,6 @@ private static void fillMethodIndex13(Map index) { index.put("com.codename1.io.usb.UsbDeviceListener", splitMembers("")); index.put("com.codename1.io.usb.UsbPlatform", splitMembers("")); index.put("com.codename1.io.webauthn.PublicKeyCredential", splitMembers("")); - } - - private static void fillMethodIndex14(Map index) { index.put("com.codename1.io.webauthn.PublicKeyCredentialCreationOptions", splitMembers("")); index.put("com.codename1.io.webauthn.PublicKeyCredentialCreationOptions.Builder", splitMembers("")); index.put("com.codename1.io.webauthn.PublicKeyCredentialRequestOptions", splitMembers("")); @@ -3042,6 +3257,9 @@ private static void fillMethodIndex14(Map index) { index.put("com.codename1.l10n.ParseException", splitMembers("")); index.put("com.codename1.l10n.SimpleDateFormat", splitMembers("")); index.put("com.codename1.location.Geofence", splitMembers("")); + } + + private static void fillMethodIndex16(Map index) { index.put("com.codename1.location.GeofenceListener", splitMembers("")); index.put("com.codename1.location.GeofenceManager", splitMembers("")); index.put("com.codename1.location.GeofenceManager.Listener", splitMembers("")); @@ -3078,9 +3296,6 @@ private static void fillMethodIndex14(Map index) { index.put("com.codename1.maps.layers.AbstractLayer", splitMembers("")); index.put("com.codename1.maps.layers.ArrowLinesLayer", splitMembers("")); index.put("com.codename1.maps.layers.Layer", splitMembers("")); - } - - private static void fillMethodIndex15(Map index) { index.put("com.codename1.maps.layers.LinesLayer", splitMembers("")); index.put("com.codename1.maps.layers.PointLayer", splitMembers("")); index.put("com.codename1.maps.layers.PointsLayer", splitMembers("")); @@ -3109,6 +3324,9 @@ private static void fillMethodIndex15(Map index) { index.put("com.codename1.maps.vector.StyleLayer", splitMembers("")); index.put("com.codename1.maps.vector.TileCallback", splitMembers("")); index.put("com.codename1.maps.vector.TileSource", splitMembers("")); + } + + private static void fillMethodIndex17(Map index) { index.put("com.codename1.maps.vector.VectorFeature", splitMembers("")); index.put("com.codename1.maps.vector.VectorLayer", splitMembers("")); index.put("com.codename1.maps.vector.VectorMapEngine", splitMembers("")); @@ -3145,9 +3363,6 @@ private static void fillMethodIndex15(Map index) { index.put("com.codename1.media.SpeechRecognizer", splitMembers("")); index.put("com.codename1.media.TextToSpeech", splitMembers("")); index.put("com.codename1.media.TimedRecognitionCallback", splitMembers("")); - } - - private static void fillMethodIndex16(Map index) { index.put("com.codename1.media.Transcriber", splitMembers("")); index.put("com.codename1.media.TranscriptionRequest", splitMembers("")); index.put("com.codename1.media.TranscriptionResult", splitMembers("")); @@ -3176,6 +3391,9 @@ private static void fillMethodIndex16(Map index) { index.put("com.codename1.nfc.NfcError", splitMembers("")); index.put("com.codename1.nfc.NfcException", splitMembers("")); index.put("com.codename1.nfc.NfcF", splitMembers("")); + } + + private static void fillMethodIndex18(Map index) { index.put("com.codename1.nfc.NfcListener", splitMembers("")); index.put("com.codename1.nfc.NfcReadOptions", splitMembers("")); index.put("com.codename1.nfc.NfcV", splitMembers("")); @@ -3212,9 +3430,6 @@ private static void fillMethodIndex16(Map index) { index.put("com.codename1.plugin.event.OpenGalleryEvent", splitMembers("")); index.put("com.codename1.plugin.event.PluginEvent", splitMembers("")); index.put("com.codename1.printing.PrintResult", splitMembers("")); - } - - private static void fillMethodIndex17(Map index) { index.put("com.codename1.printing.PrintResultListener", splitMembers("")); index.put("com.codename1.printing.Printer", splitMembers("")); index.put("com.codename1.processing.Result", splitMembers("")); @@ -3243,6 +3458,9 @@ private static void fillMethodIndex17(Map index) { index.put("com.codename1.properties.UiBinding", splitMembers("")); index.put("com.codename1.properties.UiBinding.BooleanConverter", splitMembers("")); index.put("com.codename1.properties.UiBinding.BoundTableModel", splitMembers("")); + } + + private static void fillMethodIndex19(Map index) { index.put("com.codename1.properties.UiBinding.CheckBoxRadioSelectionAdapter", splitMembers("")); index.put("com.codename1.properties.UiBinding.ComponentAdapter", splitMembers("")); index.put("com.codename1.properties.UiBinding.DateConverter", splitMembers("")); @@ -3279,9 +3497,6 @@ private static void fillMethodIndex17(Map index) { index.put("com.codename1.router.PopGuard", splitMembers("")); index.put("com.codename1.router.PopReason", splitMembers("")); index.put("com.codename1.router.RouteDispatcher", splitMembers("")); - } - - private static void fillMethodIndex18(Map index) { index.put("com.codename1.security.AuthenticationOptions", splitMembers("")); index.put("com.codename1.security.Base32", splitMembers("")); index.put("com.codename1.security.BiometricError", splitMembers("")); @@ -3305,9 +3520,14 @@ private static void fillMethodIndex18(Map index) { index.put("com.codename1.security.SecureRandom", splitMembers("")); index.put("com.codename1.security.SecureStorage", splitMembers("")); index.put("com.codename1.security.Signature", splitMembers("")); + index.put("com.codename1.security.TapjackingPolicy", splitMembers("")); + index.put("com.codename1.security.hardening.Hardening", splitMembers("")); index.put("com.codename1.security.shield.AppShield", splitMembers("")); index.put("com.codename1.security.shield.FailureMode", splitMembers("")); index.put("com.codename1.security.shield.HostPolicy", splitMembers("")); + } + + private static void fillMethodIndex20(Map index) { index.put("com.codename1.security.shield.PinSet", splitMembers("")); index.put("com.codename1.security.shield.ShieldConfig", splitMembers("")); index.put("com.codename1.security.shield.ShieldException", splitMembers("")); @@ -3346,9 +3566,6 @@ private static void fillMethodIndex18(Map index) { index.put("com.codename1.social.Login", splitMembers("")); index.put("com.codename1.social.LoginCallback", splitMembers("")); index.put("com.codename1.social.MicrosoftConnect", splitMembers("")); - } - - private static void fillMethodIndex19(Map index) { index.put("com.codename1.surfaces.LiveActivity", splitMembers("")); index.put("com.codename1.surfaces.LiveActivityDescriptor", splitMembers("")); index.put("com.codename1.surfaces.SurfaceActionEvent", splitMembers("")); @@ -3375,6 +3592,9 @@ private static void fillMethodIndex19(Map index) { index.put("com.codename1.surfaces.WidgetKind", splitMembers("")); index.put("com.codename1.surfaces.WidgetSize", splitMembers("")); index.put("com.codename1.surfaces.WidgetTimeline", splitMembers("")); + } + + private static void fillMethodIndex21(Map index) { index.put("com.codename1.surfaces.WidgetTimeline.Entry", splitMembers("")); index.put("com.codename1.surfaces.spi.SurfaceBridge", splitMembers("")); index.put("com.codename1.system.CrashReport", splitMembers("")); @@ -3413,12 +3633,9 @@ private static void fillMethodIndex19(Map index) { index.put("com.codename1.ui.CheckBox", splitMembers("accessibilityChanged()accessibilityChanged(int)addActionListener(ActionListener)addChangeListener(ActionListener)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)bindProperty(String, BindTarget)bindStateTo(Button)blocksSideSwipe()clearClientProperties()contains(int, int)containsOrOwns(int, int)createStyleAnimation(String, int)drop(Component, int, int)getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getActionListeners()getAlignment()getAllStyles()getAnimationManager()getBadgeStyleComponent()getBadgeText()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getCommand()getComponentForm()getComponentState()getCursor()getDirtyRegion()getDisabledIcon()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getFontIcon()getFontIconSize()getGap()getHeight()getIcon()getIconFont()getIconFromState()getIconStyleComponent()getIconUIID()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getListeners()getMask()getMaskName()getMaskedIcon()getMaterialIcon()getMaterialIconSize()getMaxAutoSize()getMinAutoSize()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedIcon()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getReleaseRadius()getRolloverIcon()getRolloverPressedIcon()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getShiftMillimeters()getShiftMillimetersF()getShiftText()getSideGap()getState()getStringWidth(Font)getStyle()getTabIndex()getTensileLength()getText()getTextPosition()getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVerticalAlignment()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()isAlwaysTensile()isAutoRelease()isAutoSizeMode()isBlockLead()isCapsText()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isEndsWith3Points()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isLegacyRenderer()isOpaque()isOppositeSide()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSelected()isShouldLocalize()isShowEvenIfBlank()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTextSelectionEnabled()isTickerEnabled()isTickerRunning()isToggle()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])pressed()putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)released()released(int, int)remove()removeActionListener(ActionListener)removeChangeListeners(ActionListener)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlignment(int)setAlwaysTensile(boolean)setAutoRelease(boolean)setAutoSizeMode(boolean)setBadgeText(String)setBadgeUIID(String)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCapsText(boolean)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setCommand(Command)setComponentState(Object)setCursor(int)setDirtyRegion(Rectangle)setDisabledIcon(Image)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditingDelegate(Editable)setEnabled(boolean)setEndsWith3Points(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setFontIcon(char)setFontIcon(Font, char)setFontIcon(Font, char, float)setGap(int)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIcon(Image)setIconUIID(String)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLegacyRenderer(boolean)setMask(Object)setMaskName(String)setMaterialIcon(char)setMaterialIcon(char, float)setMaxAutoSize(float)setMinAutoSize(float)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOppositeSide(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedIcon(Image)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setReleaseRadius(int)setReleased()setRippleEffect(boolean)setRolloverIcon(Image)setRolloverPressedIcon(Image)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelected(boolean)setSelectedStyle(Style)setShiftMillimeters(float)setShiftMillimeters(int)setShiftText(int)setShouldCalcPreferredSize(boolean)setShouldLocalize(boolean)setShowEvenIfBlank(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTextPosition(int)setTextSelectionEnabled(boolean)setTickerEnabled(boolean)setToggle(boolean)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalAlignment(int)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)shouldTickerStart()startEditingAsync()startTicker()startTicker(long, boolean)stopEditing(Runnable)stopTicker()stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)unbindStateFrom(Button)visibleBoundsContains(int, int)createToggle(Image)createToggle(String)createToggle(String, Image)")); index.put("com.codename1.ui.ClipboardContent", splitMembers("findPreferredMimeType(String[])getBytes(String)getData(String)getMimeTypes()getText(String)hasMimeType(String)setData(String, Object)")); index.put("com.codename1.ui.CodeCompletion", splitMembers("getDetail()getDisplayText()getInsertText()getType()setDetail(String)setType(String)")); - } - - private static void fillMethodIndex20(Map index) { index.put("com.codename1.ui.CodeCompletionProvider", splitMembers("getCompletions(CodeEditor, String, int, SuccessCallback)")); index.put("com.codename1.ui.CodeDiagnostic", splitMembers("getColumn()getEndColumn()getEndLine()getLine()getMessage()getSeverity()setSeverity(String)")); - index.put("com.codename1.ui.CodeEditor", splitMembers("accessibilityChanged()accessibilityChanged(int)add(Component)add(Image)add(String)add(Object, Component)add(Object, String)add(Object, Image)addAll(Component[]...)addChangeListener(ActionListener)addComponent(Component)addComponent(int, Component)addComponent(int, Object, Component)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addReadyListener(ActionListener)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animateHierarchy(int)animateHierarchyAndWait(int)animateHierarchyFade(int, int)animateHierarchyFadeAndWait(int, int)animateLayout(int)animateLayoutAndWait(int)animateLayoutFade(int, int)animateLayoutFadeAndWait(int, int)animateUnlayout(int, int, Runnable)animateUnlayoutAndWait(int, int)announceForAccessibility(String)applyRTL(boolean)bindProperty(String, BindTarget)blocksSideSwipe()blurEditor()clearClientProperties()contains(Component)contains(int, int)containsOrOwns(int, int)createAnimateHierarchy(int)createAnimateHierarchyFade(int, int)createAnimateLayout(int)createAnimateLayoutFade(int, int)createAnimateLayoutFadeAndWait(int, int)createAnimateUnlayout(int, int, Runnable)createReplaceTransition(Component, Component, Transition)createStyleAnimation(String, int)drop(Component, int, int)editorChanged()findDropTargetAt(int, int)findFirstFocusable()fireEditorEvent(String, String)flushReplace()focusEditor()forceRevalidate()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getChildrenAsList(boolean)getClientProperty(String)getClosestComponentTo(int, int)getCloudBoundProperty()getCloudDestinationProperty()getCompletionProvider()getComponentAt(int)getComponentAt(int, int)getComponentCount()getComponentForm()getComponentIndex(Component)getComponentState()getCursor()getCursorPosition(SuccessCallback)getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLanguage()getLayout()getLayoutHeight()getLayoutWidth()getLeadComponent()getLeadParent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getResponderAt(int, int)getSafeAreaRoot()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollIncrement()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getTabIndex()getTabSize()getTensileLength()getText(SuccessCallback)getTextSelectionSupport()getTheme()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()insertAtCursor(String)invalidate()isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEditorReady()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isNativeEditor()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isReadOnly()isRippleEffect()isSafeArea()isSafeAreaRoot()isScrollVisible()isScrollableX()isScrollableY()isShowLineNumbers()isSmoothScrolling()isSnapToGrid()isSurface()isTactileTouch()isTensileDragEnabled()isTextInputSupported()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()iterator()iterator(boolean)keyPressed(int)keyReleased(int)keyRepeated(int)layoutContainer()longPointerPress(int, int)morph(Component, Component, int, Runnable)morphAndWait(Component, Component, int)onReady(Runnable)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)remove()removeAll()removeChangeListener(ActionListener)removeComponent(Component)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeReadyListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replace(Component, Component, Transition)replace(Component, Component, Transition, Runnable, int)replaceAndWait(Component, Component, Transition)replaceAndWait(Component, Component, Transition, int)replaceAndWait(Component, Component, Transition, boolean)requestFocus()respondsToPointerEvents()revalidate()revalidateLater()revalidateWithAnimationSafety()scrollComponentToVisible(Component)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlwaysTensile(boolean)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setCompletionProvider(CodeCompletionProvider)setComponentState(Object)setCursor(int)setDiagnostics(List)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditable(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLanguage(String)setLayout(Layout)setLeadComponent(Component)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setReadOnly(boolean)setRippleEffect(boolean)setSafeArea(boolean)setSafeAreaRoot(boolean)setScrollAnimationSpeed(int)setScrollIncrement(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setScrollable(boolean)setScrollableX(boolean)setScrollableY(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setShowLineNumbers(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTabSize(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTheme(String)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUIManager(UIManager)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()startTextInput(TextInputClient, TextInputConfig)stopEditing(Runnable)stopTextInput(Object)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTabIndices(int)updateTextInputState(Object, TextInputState)visibleBoundsContains(int, int)getRegisteredSyntaxHighlighter(String)registerSyntaxHighlighter(String, SyntaxHighlighter)")); + index.put("com.codename1.ui.CodeEditor", splitMembers("accessibilityChanged()accessibilityChanged(int)add(Component)add(Image)add(String)add(Object, Component)add(Object, String)add(Object, Image)addAll(Component[]...)addChangeListener(ActionListener)addComponent(Component)addComponent(int, Component)addComponent(int, Object, Component)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addProtectedEditListener(ActionListener)addPullToRefresh(Runnable)addReadyListener(ActionListener)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animateHierarchy(int)animateHierarchyAndWait(int)animateHierarchyFade(int, int)animateHierarchyFadeAndWait(int, int)animateLayout(int)animateLayoutAndWait(int)animateLayoutFade(int, int)animateLayoutFadeAndWait(int, int)animateUnlayout(int, int, Runnable)animateUnlayoutAndWait(int, int)announceForAccessibility(String)applyRTL(boolean)bindProperty(String, BindTarget)blocksSideSwipe()blurEditor()clearClientProperties()contains(Component)contains(int, int)containsOrOwns(int, int)createAnimateHierarchy(int)createAnimateHierarchyFade(int, int)createAnimateLayout(int)createAnimateLayoutFade(int, int)createAnimateLayoutFadeAndWait(int, int)createAnimateUnlayout(int, int, Runnable)createReplaceTransition(Component, Component, Transition)createStyleAnimation(String, int)drop(Component, int, int)editorChanged()findDropTargetAt(int, int)findFirstFocusable()fireEditorEvent(String, String)flushReplace()focusEditor()forceRevalidate()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getChildrenAsList(boolean)getClientProperty(String)getClosestComponentTo(int, int)getCloudBoundProperty()getCloudDestinationProperty()getCompletionProvider()getComponentAt(int)getComponentAt(int, int)getComponentCount()getComponentForm()getComponentIndex(Component)getComponentState()getCursor()getCursorPosition(SuccessCallback)getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLanguage()getLayout()getLayoutHeight()getLayoutWidth()getLeadComponent()getLeadParent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getResponderAt(int, int)getSafeAreaRoot()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollIncrement()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getTabIndex()getTabSize()getTensileLength()getText(SuccessCallback)getTextSelectionSupport()getTheme()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()insertAtCursor(String)invalidate()isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEditorReady()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isNativeEditor()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isReadOnly()isRippleEffect()isSafeArea()isSafeAreaRoot()isScrollVisible()isScrollableX()isScrollableY()isShowLineNumbers()isSmoothScrolling()isSnapToGrid()isSurface()isTactileTouch()isTensileDragEnabled()isTextInputSupported()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()iterator()iterator(boolean)keyPressed(int)keyReleased(int)keyRepeated(int)layoutContainer()longPointerPress(int, int)morph(Component, Component, int, Runnable)morphAndWait(Component, Component, int)onReady(Runnable)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)remove()removeAll()removeChangeListener(ActionListener)removeComponent(Component)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeProtectedEditListener(ActionListener)removeReadyListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replace(Component, Component, Transition)replace(Component, Component, Transition, Runnable, int)replaceAndWait(Component, Component, Transition)replaceAndWait(Component, Component, Transition, int)replaceAndWait(Component, Component, Transition, boolean)requestFocus()respondsToPointerEvents()revalidate()revalidateLater()revalidateWithAnimationSafety()scrollComponentToVisible(Component)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlwaysTensile(boolean)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setCompletionProvider(CodeCompletionProvider)setComponentState(Object)setCursor(int)setCursorPosition(int)setDiagnostics(List)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditable(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLanguage(String)setLayout(Layout)setLeadComponent(Component)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setProtectedRegionMarkers(String, String)setPullToRefresh(Runnable)setRTL(boolean)setReadOnly(boolean)setRippleEffect(boolean)setSafeArea(boolean)setSafeAreaRoot(boolean)setScrollAnimationSpeed(int)setScrollIncrement(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setScrollable(boolean)setScrollableX(boolean)setScrollableY(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setShowLineNumbers(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTabSize(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTheme(String)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUIManager(UIManager)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()startTextInput(TextInputClient, TextInputConfig)stopEditing(Runnable)stopTextInput(Object)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTabIndices(int)updateTextInputState(Object, TextInputState)visibleBoundsContains(int, int)getRegisteredSyntaxHighlighter(String)registerSyntaxHighlighter(String, SyntaxHighlighter)")); index.put("com.codename1.ui.ComboBox", splitMembers("accessibilityChanged()accessibilityChanged(int)addActionListener(ActionListener)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addSelectionListener(SelectionListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)bindProperty(String, BindTarget)blocksSideSwipe()clearClientProperties()contains(int, int)containsOrOwns(int, int)createStyleAnimation(String, int)drop(Component, int, int)getAbsoluteX()getAbsoluteY()getAccessibilityItemBounds(int, Rectangle)getAccessibilityItemText(int)getAccessibilityNode()getAccessibilityText()getAccessibilityVisibleItemIndices()getActionListeners()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getComboBoxImage()getComponentForm()getComponentState()getCurrentSelected()getCursor()getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getFixedSelection()getHeight()getHint()getHintIcon()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getItemGap()getLabelForComponent()getListSizeCalculationSampleCount()getListeners()getMaxElementHeight()getMinElementHeight()getModel()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOrientation()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPopupPlacement()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getRenderer()getRenderingPrototype()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedIndex()getSelectedItem()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()isActAsSpinnerDialog()isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isCommandList()isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnoreFocusComponentWhenUnfocused()isIgnorePointerEvents()isIncludeSelectCancel()isLongPointerPressActionEnabled()isMutableRendererBackgrounds()isNumericKeyActions()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isShowingPopupDialog()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)remove()removeActionListener(ActionListener)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeSelectionListener(SelectionListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)requestFocus()respondsToPointerEvents()scrollRectToVisible(Rectangle)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setActAsSpinnerDialog(boolean)setAlwaysTensile(boolean)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComboBoxImage(Image)setCommandList(boolean)setComponentState(Object)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFireOnClick(boolean)setFixedSelection(int)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHint(String)setHint(String, Image)setHintIcon(Image)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnoreFocusComponentWhenUnfocused(boolean)setIgnorePointerEvents(boolean)setIncludeSelectCancel(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setInputOnFocus(boolean)setIsScrollVisible(boolean)setItemGap(int)setLabelForComponent(Label)setListCellRenderer(ListCellRenderer)setListSizeCalculationSampleCount(int)setLongPointerPressActionEnabled(boolean)setMaxElementHeight(int)setMinElementHeight(int)setModel(ListModel)setMutableRendererBackgrounds(boolean)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setNumericKeyActions(boolean)setOpaque(boolean)setOrientation(int)setOwner(Component)setPaintFocusBehindList(boolean)setPinchBlocksDragAndDrop(boolean)setPopupPlacement(int)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRenderer(ListCellRenderer)setRippleEffect(boolean)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollToSelected(boolean)setScrollVisible(boolean)setSelectCommandText(String)setSelectedIndex(int)setSelectedIndex(int, boolean)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)size()startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)visibleBoundsContains(int, int)isDefaultActAsSpinnerDialog()isDefaultIncludeSelectCancel()setDefaultActAsSpinnerDialog(boolean)setDefaultIncludeSelectCancel(boolean)")); index.put("com.codename1.ui.Command", splitMembers("actionPerformed(ActionEvent)equals(Object)getClientProperty(String)getCommandName()getDesktopMenu()getDesktopShortcutKeyChar()getDesktopShortcutModifiers()getDisabledIcon()getIcon()getIconFont()getIconGapMM()getId()getMaterialIcon()getMaterialIconSize()getPressedIcon()getRolloverIcon()hashCode()isDisposesDialog()isEnabled()putClientProperty(String, Object)setCommandName(String)setDesktopMenu(String)setDesktopShortcut(char)setDesktopShortcut(char, int)setDisabledIcon(Image)setDisposesDialog(boolean)setEnabled(boolean)setIcon(Image)setIconFont(Font)setIconGapMM(float)setMaterialIcon(char)setMaterialIconSize(float)setPressedIcon(Image)setRolloverIcon(Image)toString()create(String, Image, ActionListener)createMaterial(String, char, ActionListener)")); index.put("com.codename1.ui.CommonProgressAnimations", splitMembers("")); @@ -3437,11 +3654,14 @@ private static void fillMethodIndex20(Map index) { index.put("com.codename1.ui.Container", splitMembers("accessibilityChanged()accessibilityChanged(int)add(Component)add(Image)add(String)add(Object, Component)add(Object, String)add(Object, Image)addAll(Component[]...)addComponent(Component)addComponent(int, Component)addComponent(int, Object, Component)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animateHierarchy(int)animateHierarchyAndWait(int)animateHierarchyFade(int, int)animateHierarchyFadeAndWait(int, int)animateLayout(int)animateLayoutAndWait(int)animateLayoutFade(int, int)animateLayoutFadeAndWait(int, int)animateUnlayout(int, int, Runnable)animateUnlayoutAndWait(int, int)announceForAccessibility(String)applyRTL(boolean)bindProperty(String, BindTarget)blocksSideSwipe()clearClientProperties()contains(Component)contains(int, int)containsOrOwns(int, int)createAnimateHierarchy(int)createAnimateHierarchyFade(int, int)createAnimateLayout(int)createAnimateLayoutFade(int, int)createAnimateLayoutFadeAndWait(int, int)createAnimateUnlayout(int, int, Runnable)createReplaceTransition(Component, Component, Transition)createStyleAnimation(String, int)drop(Component, int, int)findDropTargetAt(int, int)findFirstFocusable()flushReplace()forceRevalidate()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getChildrenAsList(boolean)getClientProperty(String)getClosestComponentTo(int, int)getCloudBoundProperty()getCloudDestinationProperty()getComponentAt(int)getComponentAt(int, int)getComponentCount()getComponentForm()getComponentIndex(Component)getComponentState()getCursor()getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLayout()getLayoutHeight()getLayoutWidth()getLeadComponent()getLeadParent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getResponderAt(int, int)getSafeAreaRoot()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollIncrement()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()invalidate()isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isSafeArea()isSafeAreaRoot()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isSurface()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()iterator()iterator(boolean)keyPressed(int)keyReleased(int)keyRepeated(int)layoutContainer()longPointerPress(int, int)morph(Component, Component, int, Runnable)morphAndWait(Component, Component, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)remove()removeAll()removeComponent(Component)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replace(Component, Component, Transition)replace(Component, Component, Transition, Runnable, int)replaceAndWait(Component, Component, Transition)replaceAndWait(Component, Component, Transition, int)replaceAndWait(Component, Component, Transition, boolean)requestFocus()respondsToPointerEvents()revalidate()revalidateLater()revalidateWithAnimationSafety()scrollComponentToVisible(Component)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlwaysTensile(boolean)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLayout(Layout)setLeadComponent(Component)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setSafeArea(boolean)setSafeAreaRoot(boolean)setScrollAnimationSpeed(int)setScrollIncrement(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setScrollable(boolean)setScrollableX(boolean)setScrollableY(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUIManager(UIManager)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTabIndices(int)visibleBoundsContains(int, int)encloseIn(Layout, Component[]...)encloseIn(Layout, Component, Object)")); index.put("com.codename1.ui.DevicePosture", splitMembers("getFoldBounds(Rectangle)getFoldOrientation()getHingeAngle()getPosture()isFoldable()isSeparating()isTableTop()getInstance()")); index.put("com.codename1.ui.Dialog", splitMembers("accessibilityChanged()accessibilityChanged(int)add(Component)add(Image)add(String)add(Object, Component)add(Object, String)add(Object, Image)addAll(Component[]...)addCommand(Command)addCommand(Command, int)addCommandListener(ActionListener)addComponent(Component)addComponent(int, Component)addComponent(int, Object, Component)addComponentAwaitingRelease(Component)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addGameKeyListener(int, ActionListener)addKeyListener(int, ActionListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addOrientationListener(ActionListener)addPasteListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addShowListener(ActionListener)addSizeChangedListener(ActionListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animateHierarchy(int)animateHierarchyAndWait(int)animateHierarchyFade(int, int)animateHierarchyFadeAndWait(int, int)animateLayout(int)animateLayoutAndWait(int)animateLayoutFade(int, int)animateLayoutFadeAndWait(int, int)animateUnlayout(int, int, Runnable)animateUnlayoutAndWait(int, int)announceForAccessibility(String)applyRTL(boolean)bindProperty(String, BindTarget)blocksSideSwipe()checkPopGuard(PopReason)clearClientProperties()clearComponentsAwaitingRelease()configureCommands(Command[], boolean)contains(Component)contains(int, int)containsOrOwns(int, int)createAnimateHierarchy(int)createAnimateHierarchyFade(int, int)createAnimateLayout(int)createAnimateLayoutFade(int, int)createAnimateLayoutFadeAndWait(int, int)createAnimateUnlayout(int, int, Runnable)createReplaceTransition(Component, Component, Transition)createStyleAnimation(String, int)deregisterAnimated(Animation)dispatchCommand(Command, ActionEvent)dispatchPaste(ActionEvent)dispose()drop(Component, int, int)findCurrentlyEditingComponent()findDropTargetAt(int, int)findFirstFocusable()findNextFocusHorizontal(boolean)findNextFocusVertical(boolean)flushReplace()forceRevalidate()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBackCommand()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBlurBackgroundRadius()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getChildrenAsList(boolean)getClearCommand()getClientProperty(String)getClosestComponentTo(int, int)getCloudBoundProperty()getCloudDestinationProperty()getCommand(int)getCommandCount()getComponentAt(int)getComponentAt(int, int)getComponentCount()getComponentForm()getComponentIndex(Component)getComponentState()getContentPane()getCurrentInputDevice()getCursor()getDefaultCommand()getDialogComponent()getDialogPosition()getDialogPreferredSize()getDialogStyle()getDialogType()getDialogUIID()getDirtyRegion()getDisabledStyle()getDragRegionStatus(int, int)getDragTransparency()getDraggedx()getDraggedy()getEditOnShow()getEditingDelegate()getFocused()getFormLayeredPane(Class, boolean)getGlassPane()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getInvisibleAreaUnderVKB()getLabelForComponent()getLayeredPane()getLayeredPane(Class, boolean)getLayeredPane(Class, int)getLayout()getLayoutHeight()getLayoutWidth()getLeadComponent()getLeadParent()getMenuBar()getMenuStyle()getName()getNativeOverlay()getNextComponent(Component)getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPopGuard()getPopupDirectionBiasPortrait()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPreviousComponent(Component)getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getResponderAt(int, int)getSafeArea()getSafeAreaRoot()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollIncrement()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getSoftButton(int)getSoftButtonCount()getSourceCommand()getStyle()getTabIndex()getTabIterator(Component)getTensileLength()getTextSelection()getTextSelectionSupport()getTintColor()getTitle()getTitleArea()getTitleComponent()getTitleStyle()getToolbar()getTooltip()getTransitionInAnimator()getTransitionOutAnimator()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()grabAnimationLock()growOrShrink()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()hasMedia()invalidate()isAlwaysTensile()isAutoDispose()isBlockLead()isCellRenderer()isChildOf(Container)isCyclicFocus()isDisposeWhenPointerOutOfBounds()isDragRegion(int, int)isDraggable()isDropTarget()isEditable()isEditing()isEnableCursors()isEnabled()isFlatten()isFocusScrolling()isFocusable()isFormBottomPaddingEditingMode()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isInteractionDialogMode()isMinimizeOnBack()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isSafeArea()isSafeAreaRoot()isScrollVisible()isScrollable()isScrollableX()isScrollableY()isSingleFocusMode()isSmoothScrolling()isSnapToGrid()isSurface()isTactileTouch()isTensileDragEnabled()isTitleCentered()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()iterator()iterator(boolean)keyPressed(int)keyReleased(int)keyRepeated(int)layoutContainer()longPointerPress(int, int)morph(Component, Component, int, Runnable)morphAndWait(Component, Component, int)paint(Graphics)paintBackground(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)placeButtonCommands(Command[])pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)registerAnimated(Animation)releaseAnimationLock()remove()removeAll()removeAllCommands()removeAllShowListeners()removeCommand(Command)removeCommandListener(ActionListener)removeComponent(Component)removeComponentAwaitingRelease(Component)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeGameKeyListener(int, ActionListener)removeKeyListener(int, ActionListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removeOrientationListener(ActionListener)removePasteListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeShowListener(ActionListener)removeSizeChangedListener(ActionListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replace(Component, Component, Transition)replace(Component, Component, Transition, Runnable, int)replaceAndWait(Component, Component, Transition)replaceAndWait(Component, Component, Transition, int)replaceAndWait(Component, Component, Transition, boolean)requestFocus()respondsToPointerEvents()revalidate()revalidateLater()revalidateWithAnimationSafety()scrollComponentToVisible(Component)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAllowEnableLayoutOnPaint(boolean)setAlwaysTensile(boolean)setAutoDispose(boolean)setBackCommand(Command)setBackCommand(String, Image, ActionListener)setBgImage(Image)setBlockLead(boolean)setBlurBackgroundRadius(float)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setClearCommand(Command)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setCurrentInputDevice(VirtualInputDevice)setCursor(int)setCyclicFocus(boolean)setDefaultCommand(Command)setDialogPosition(String)setDialogStyle(Style)setDialogType(int)setDialogUIID(String)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDisposeWhenPointerOutOfBounds(boolean)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditOnShow(TextArea)setEditingDelegate(Editable)setEnableCursors(boolean)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusScrolling(boolean)setFocusable(boolean)setFocused(Component)setFormBottomPaddingEditingMode(boolean)setGlassPane(Painter)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setInteractionDialogMode(boolean)setIsScrollVisible(boolean)setLabelForComponent(Label)setLayout(Layout)setLeadComponent(Component)setMenuBar(MenuBar)setMenuCellRenderer(ListCellRenderer)setMenuTransitions(Transition, Transition)setMinimizeOnBack(boolean)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOverrideInvisibleAreaUnderVKB(int)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPopGuard(PopGuard)setPopupDirectionBiasPortrait(Boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPreviousForm(Form)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setSafeArea(boolean)setSafeAreaChanged()setSafeAreaRoot(boolean)setScrollAnimationSpeed(int)setScrollIncrement(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setScrollable(boolean)setScrollableX(boolean)setScrollableY(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setSourceCommand(Command)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setTimeout(long)setTintColor(int)setTitle(String)setTitleCentered(boolean)setTitleComponent(Label)setTitleComponent(Label, Transition)setTitleStyle(Style)setToolBar(Toolbar)setToolbar(Toolbar)setTooltip(String)setTransitionInAnimator(Transition)setTransitionOutAnimator(Transition)setTransitions(Transition)setTraversable(boolean)setUIID(String)setUIID(String, String)setUIIDByPopupPosition(boolean)setUIManager(UIManager)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)show()show(int, int, int, int)show(int, int, int, int, boolean)show(int, int, int, int, boolean, boolean)showAtPosition(int, int, int, int, boolean)showBack()showDialog()showModeless()showPacked(String, boolean)showPopupDialog(Component)showPopupDialog(Rectangle)showStetched(String, boolean)showStretched(String, boolean)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTabIndices(int)visibleBoundsContains(int, int)wasDisposedDueToOutOfBoundsTouch()wasDisposedDueToRotation()getDefaultBlurBackgroundRadius()getDefaultDialogPosition()getDefaultDialogType()isAutoAdjustDialogSize()isCommandsAsButtons()isDefaultDisposeWhenPointerOutOfBounds()isDefaultInteractionDialogMode()isDefaultTitleCentered()isDisableStaticDialogScrolling()setAutoAdjustDialogSize(boolean)setCommandsAsButtons(boolean)setDefaultBlurBackgroundRadius(float)setDefaultDialogPosition(String)setDefaultDialogType(int)setDefaultDisposeWhenPointerOutOfBounds(boolean)setDefaultInteractionDialogMode(boolean)setDefaultTitleCentered(boolean)setDisableStaticDialogScrolling(boolean)show(String, Component, Command[]...)show(String, String, Command[]...)show(String, String, String, String)show(String, Component, Command[], int, Image)show(String, String, int, Image, String, String)show(String, String, Command[], int, Image, long)show(String, Component, Command[], int, Image, long)show(String, String, int, Image, String, String, long)show(String, String, Command, Command[], int, Image, long)show(String, String, Command[], int, Image, long, Transition)show(String, Component, Command[], int, Image, long, Transition)show(String, String, Command, Command[], int, Image, long, Transition)show(String, Component, Command, Command[], int, Image, long, Transition)")); - index.put("com.codename1.ui.Display", splitMembers("accessibilityTreeChanged(int)addCompletionHandler(Media, Runnable)addEdtErrorHandler(ActionListener)addMessageListener(ActionListener)addPostureListener(ActionListener)addVirtualKeyboardListener(ActionListener)addWindowListener(ActionListener)announceForAccessibility(String)announceForAccessibility(Component, String)areMutableImagesFast()callSerially(Runnable)callSeriallyAndWait(Runnable)callSeriallyAndWait(Runnable, int)callSeriallyOnIdle(Runnable)canDial()canExecute(String)canForceOrientation()canInstallOnHomescreen()cancelBackgroundProcessing(String)cancelBackgroundWork(String)cancelLocalNotification(String)captureAudio(ActionListener)captureAudio(MediaRecorderBuilder, ActionListener)capturePhoto(ActionListener)captureScreen()captureVideo(ActionListener)captureVideo(VideoCaptureConstraints, ActionListener)confirmAttestation(String)consumePendingNativeCrash()convertBidiLogicalToVisual(String)convertToPixels(float)convertToPixels(float, byte)convertToPixels(int, boolean)convertToPixels(float, byte, boolean)copyToClipboard(ClipboardContent)createBackgroundMedia(String)createBackgroundMediaAsync(String)createContact(String, String, String, String, String, String)createGpuPeer(RenderView)createMedia(String, boolean, Runnable)createMediaAsync(String, boolean, Runnable)createMediaRecorder(MediaRecorderBuilder)createMediaRecorder(String)createMediaRecorder(String, String)createNotificationChannelGroup(String, String)createSFSymbolImage(String, int, float, int)createSoftWeakRef(Object)createSoundPool(int)createThread(Runnable, String)delete(String)deleteContact(String)deleteNotificationChannel(String)deregisterPush()dial(String)dismissNotification(Object)dispatchMessage(MessageEvent)downloadBytesAsFile(String, byte[])editString(Component, int, int, String)editString(Component, int, int, String, int)execute(String)execute(String, ActionListener)exists(String)exitApplication()exitFullScreen()extractHardRef(Object)fireMagnifyGesture(int, int, float)fireMouseWheelEvent(int, int, int, int, boolean, int)fireRotationGesture(int, int, float)fireVirtualKeyboardEvent(boolean)fireWindowEvent(WindowEvent)flashBacklight(int)gaussianBlurImage(Image, float)getAllContacts(boolean)getAllContacts(boolean, boolean, boolean, boolean, boolean, boolean)getAppSignerDigests()getAvailableRecordingMimeTypes()getBiometrics()getBluetooth()getBonjourPlatform()getCarBridge()getCharLocation(String, int)getClipboardContent()getCodeScanner()getColorVisionDeficiency()getCommandBehavior()getCompromiseReasons()getContactById(String)getContactById(String, boolean, boolean, boolean, boolean, boolean)getCrashReporter()getCurrent()getCurrentPointerEvent()getDatabasePath(String)getDensityStr()getDesktopSize()getDeviceDensity()getDevicePosture()getDisplayCount()getDisplayHeight()getDisplaySafeArea(Rectangle)getDisplayWidth()getDragSpeed(boolean)getDragStartPercentage()getEnabledAccessibilityServices()getFrameRate()getGameAction(int)getHealth()getImageIO()getInAppPurchase()getInAppPurchase(boolean)getInitialWindowSizeHintPercent()getInvisibleAreaUnderVKB()getKeyCode(int)getKeyboardType()getLargerTextScale()getLineSeparator()getLinkedContactIds(Contact)getLocalCalendarSource()getLocalizationManager()getLocationManager()getLongPointerPressInterval()getMediaRecorderingMimeType()getMotionSensorManager()getMsisdn()getNativeLogSnapshot()getNetworkTypePlatform()getNfc()getPasteDataFromClipboard()getPlatformName()getPlatformOverrides()getPluginSupport()getPointerButton()getPointerContactSize()getPointerPressure()getPointerTiltX()getPointerTiltY()getPointerType()getPreferredBackgroundFetchInterval(int)getPressedButtonMask()getProjectBuildHints()getProperty(String, String)getSMSSupport()getSecureStorage()getSharedJavascriptContext()getShowDuringEditBehavior()getStackTrace(Thread, Throwable)getSupportedVirtualKeyboard()getSurfaceBridge()getUdid()getUsbPlatform()getVideoIO()getVirtualKeyboardListener()getWearableBridge()getWifiDirectPlatform()getWifiPlatform()getWindowBounds()gpuRequestRender(PeerComponent)gpuSetContinuous(PeerComponent, boolean)hasCamera()hasDragOccured()hasNativeTheme()hideNotify()installNativeCrashHandler()installNativeTheme()invokeAndBlock(Runnable)invokeAndBlock(Runnable, boolean)invokeWithoutBlocking(Runnable)invokeWithoutBlockingWithResultSync(RunnableWithResultSync)isAccessibilityTreeSupported()isAccessibilityTreeUpdateRequired()isAllowMinimizing()isAltGraphKeyDown()isAltKeyDown()isAttestationSupported()isAutoFoldVKBOnFormSwitch()isBackgroundFetchSupported()isBackgroundProcessingSupported()isBackgroundWorkSupported()isBadgingSupported()isBidiAlgorithm()isBoldTextEnabled()isBuiltinSoundAvailable(String)isBuiltinSoundsEnabled()isCallDetectionSupported()isCarConnected()isClickTouchScreen()isContactsPermissionGranted()isControlKeyDown()isDarkMode()isDatabaseCustomPathSupported()isDebuggableBuild()isDesktop()isDesktopMode()isDeviceCompromised()isDifferentiateWithoutColorEnabled()isEdt()isEnableAsyncStackTraces()isExternalDisplayConnected()isFoldable()isForegroundServiceSupported()isFullScreenSupported()isGalleryTypeSupported(int)isGaussianBlurSupported()isGetAllContactsFast()isGpuSupported()isGrayscaleEnabled()isHighContrastEnabled()isInCall()isInFullScreenMode()isInTransition()isInvertColorsEnabled()isJailbrokenDevice()isLargerTextEnabled()isLockOrientation()isMetaKeyDown()isMinimized()isMultiKeyMode()isMultiTouch()isNativeCommands()isNativeInAppReviewSupported()isNativeInputSupported()isNativePickerTypeSupported(int)isNativeShareSupported()isNativeTitle()isNativeVideoPlayerControlsIncluded()isNotificationSupported()isOnOffSwitchLabelsEnabled()isOpenNativeNavigationAppSupported()isPortrait()isPrintingSupported()isPureTouch()isRTL(char)isReceiveSharedContentSupported()isReduceMotionEnabled()isReduceTransparencyEnabled()isRightMouseButtonDown()isScreenReaderEnabled()isScreenSaverDisableSupported()isScrollWheeling()isShiftKeyDown()isSimulator()isSoundPoolSupported()isSpeechRecognitionSupported()isStylusPointer()isTV()isTablet()isTextToSpeechSupported()isThirdSoftButton()isTouchScreenDevice()isVirtualKeyboardShowing()isWalletExtensionSupported()isWatch()keyPressed(int)keyReleased(int)lockOrientation(boolean)minimizeApplication()notifyPushCompletion()notifyStatusBar(String, String, String, boolean, boolean)notifyStatusBar(String, String, String, boolean, boolean, Hashtable)numAlphaLevels()numColors()onCanInstallOnHomescreen(Runnable)onEditingComplete(Component, String)openFileChooser(ActionListener, String)openGallery(ActionListener, int)openImageGallery(ActionListener)openNativeNavigationApp(String)openNativeNavigationApp(double, double)openOrCreate(String)platformUsesInputMode()playBuiltinSound(String)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int[], int[])pointerReleased(int[], int[])postMessage(MessageEvent)postureChanged()print(String, String, PrintResultListener)promptInstallOnHomescreen()refreshContacts()refreshNativeTitle()registerNotificationChannel(NotificationChannelBuilder)registerPush()registerPush(String, boolean)registerPush(Hashtable, boolean)removeCompletionHandler(Media, Runnable)removeEdtErrorHandler(ActionListener)removeMessageListener(ActionListener)removePostureListener(ActionListener)removeVirtualKeyboardListener(ActionListener)removeWindowListener(ActionListener)requestFullScreen()requestIntegrityToken(String)requestNativeInAppReview(SuccessCallback)requestNotificationPermission(NotificationPermissionCallback)requestNotificationPermission(NotificationPermissionRequest, NotificationPermissionCallback)resetAttestation()restoreMinimizedApplication()restoreToBookmark()scheduleBackgroundProcessing(String, long, boolean, boolean, Runnable)scheduleBackgroundTask(Runnable)scheduleBackgroundWork(WorkRequest)scheduleLocalNotification(LocalNotification, long, int)screenshot(SuccessCallback)sendMessage(String[], String, Message)sendSMS(String, String)sendSMS(String, String, boolean)setAllowMinimizing(boolean)setAutoFoldVKBOnFormSwitch(boolean)setBadgeNumber(int)setBidiAlgorithm(boolean)setBookmark(Runnable)setBuiltinSoundsEnabled(boolean)setCommandBehavior(int)setCrashReporter(CrashReport)setDarkMode(Boolean)setDragStartPercentage(int)setEnableAsyncStackTraces(boolean)setFramerate(int)setInitialWindowSizeHintPercent(Dimension)setInterval(int, Runnable)setLongPointerPressInterval(int)setMultiKeyMode(boolean)setNativeCommands(boolean)setNoSleep(boolean)setPollingFrequency(int)setPreferredBackgroundFetchInterval(int)setProjectBuildHint(String, String)setProperty(String, String)setPureTouch(boolean)setScreenSaverEnabled(boolean)setSecureScreen(boolean)setShowDuringEditBehavior(int)setShowVirtualKeyboard(boolean)setThirdSoftButton(boolean)setTimeout(int, Runnable)setTouchScreenDevice(boolean)setTransitionYield(int)setVirtualKeyboardListener(ActionListener)setWindowSize(int, int)share(String)share(String, String, String)share(String, String, String, Rectangle)share(String, String, String, Rectangle, ShareResultListener)shouldRenderSelection()shouldRenderSelection(Component)showNativePicker(int, Component, Object, Object)showNativeScreen(Object)showNotify()sizeChanged(int, int)startForegroundService(String, String, String, String, Task, ForegroundService)startRemoteControl()startSpeechRecognition(RecognitionOptions, RecognitionCallback)startThread(Runnable, String)stopEditing(Component)stopEditing(Component, Runnable)stopForegroundService(Object)stopRemoteControl()stopSpeechRecognition()subscribeToPushTopic(String)textToSpeechAvailableVoices()textToSpeechSpeak(String, TtsOptions)textToSpeechStop()unlockOrientation()unsubscribeFromPushTopic(String)updateForegroundServiceNotification(Object, String, String)vibrate(int)walletExtensionClear()walletExtensionSetAuthToken(String)walletExtensionSetPassEntries(boolean, WalletPassEntry[])walletExtensionSetRequiresAuthentication(boolean)deinitialize()getInstance()init(Object)isInitialized()")); + index.put("com.codename1.ui.Display", splitMembers("accessibilityTreeChanged(int)addCompletionHandler(Media, Runnable)addEdtErrorHandler(ActionListener)addMessageListener(ActionListener)addPostureListener(ActionListener)addTapjackingListener(ActionListener)addVirtualKeyboardListener(ActionListener)addWindowListener(ActionListener)announceForAccessibility(String)announceForAccessibility(Component, String)areMutableImagesFast()callSerially(Runnable)callSeriallyAndWait(Runnable)callSeriallyAndWait(Runnable, int)callSeriallyOnIdle(Runnable)canDial()canExecute(String)canForceOrientation()canInstallOnHomescreen()cancelBackgroundProcessing(String)cancelBackgroundWork(String)cancelLocalNotification(String)captureAudio(ActionListener)captureAudio(MediaRecorderBuilder, ActionListener)capturePhoto(ActionListener)captureScreen()captureVideo(ActionListener)captureVideo(VideoCaptureConstraints, ActionListener)confirmAttestation(String)consumePendingNativeCrash()convertBidiLogicalToVisual(String)convertToPixels(float)convertToPixels(float, byte)convertToPixels(int, boolean)convertToPixels(float, byte, boolean)copyToClipboard(ClipboardContent)createBackgroundMedia(String)createBackgroundMediaAsync(String)createContact(String, String, String, String, String, String)createGpuPeer(RenderView)createMedia(String, boolean, Runnable)createMediaAsync(String, boolean, Runnable)createMediaRecorder(MediaRecorderBuilder)createMediaRecorder(String)createMediaRecorder(String, String)createNotificationChannelGroup(String, String)createSFSymbolImage(String, int, float, int)createSoftWeakRef(Object)createSoundPool(int)createThread(Runnable, String)databaseIdentityForEngineFile(String)databaseManagedKeyIdentity(String)databaseRegistryIdentity(String)delete(String)deleteContact(String)deleteNotificationChannel(String)deregisterPush()dial(String)dismissNotification(Object)dispatchMessage(MessageEvent)downloadBytesAsFile(String, byte[])editString(Component, int, int, String)editString(Component, int, int, String, int)execute(String)execute(String, ActionListener)exists(String)exitApplication()exitFullScreen()extractHardRef(Object)fireMagnifyGesture(int, int, float)fireMouseWheelEvent(int, int, int, int, boolean, int)fireRotationGesture(int, int, float)fireVirtualKeyboardEvent(boolean)fireWindowEvent(WindowEvent)flashBacklight(int)gaussianBlurImage(Image, float)getAllContacts(boolean)getAllContacts(boolean, boolean, boolean, boolean, boolean, boolean)getAppSignerDigests()getAvailableRecordingMimeTypes()getBiometrics()getBluetooth()getBonjourPlatform()getCarBridge()getCharLocation(String, int)getClipboardContent()getCodeScanner()getColorVisionDeficiency()getCommandBehavior()getCompromiseReasons()getContactById(String)getContactById(String, boolean, boolean, boolean, boolean, boolean)getCrashReporter()getCurrent()getCurrentPointerEvent()getDatabasePath(String)getDensityStr()getDesktopSize()getDeviceDensity()getDevicePosture()getDisplayCount()getDisplayHeight()getDisplaySafeArea(Rectangle)getDisplayWidth()getDragSpeed(boolean)getDragStartPercentage()getEnabledAccessibilityServices()getFrameRate()getGameAction(int)getHealth()getHomeBridge()getImageIO()getInAppPurchase()getInAppPurchase(boolean)getInitialWindowSizeHintPercent()getIntentBridge()getInvisibleAreaUnderVKB()getKeyCode(int)getKeyboardType()getLargerTextScale()getLineSeparator()getLinkedContactIds(Contact)getLocalCalendarSource()getLocalizationManager()getLocationManager()getLongPointerPressInterval()getMediaRecorderingMimeType()getMotionSensorManager()getMsisdn()getNativeLogSnapshot()getNetworkTypePlatform()getNfc()getPasteDataFromClipboard()getPlatformName()getPlatformOverrides()getPluginSupport()getPointerButton()getPointerContactSize()getPointerPressure()getPointerTiltX()getPointerTiltY()getPointerType()getPreferredBackgroundFetchInterval(int)getPressedButtonMask()getProjectBuildHints()getProperty(String, String)getSMSSupport()getSecureStorage()getSharedJavascriptContext()getShowDuringEditBehavior()getStackTrace(Thread, Throwable)getSupportedVirtualKeyboard()getSurfaceBridge()getTapjackingPolicy()getUdid()getUsbPlatform()getVideoIO()getVirtualKeyboardListener()getWearableBridge()getWifiDirectPlatform()getWifiPlatform()getWindowBounds()gpuRequestRender(PeerComponent)gpuSetContinuous(PeerComponent, boolean)hasCamera()hasDragOccured()hasNativeTheme()hideNotify()installNativeCrashHandler()installNativeTheme()invokeAndBlock(Runnable)invokeAndBlock(Runnable, boolean)invokeWithoutBlocking(Runnable)invokeWithoutBlockingWithResultSync(RunnableWithResultSync)isAccessibilityTreeSupported()isAccessibilityTreeUpdateRequired()isAllowMinimizing()isAltGraphKeyDown()isAltKeyDown()isAttestationSupported()isAutoFoldVKBOnFormSwitch()isBackgroundFetchSupported()isBackgroundProcessingSupported()isBackgroundWorkSupported()isBadgingSupported()isBidiAlgorithm()isBlobQueryParameterSupported()isBoldTextEnabled()isBuiltinSoundAvailable(String)isBuiltinSoundsEnabled()isCallDetectionSupported()isCarConnected()isClickTouchScreen()isContactsPermissionGranted()isControlKeyDown()isDarkMode()isDatabaseCustomPathSupported()isDatabaseEncryptionSupported()isDatabaseFileEncrypted(String)isDatabaseManagedKeyHardwareBacked()isDebuggableBuild()isDesktop()isDesktopMode()isDeviceCompromised()isDifferentiateWithoutColorEnabled()isEdt()isEnableAsyncStackTraces()isExternalDisplayConnected()isFoldable()isForegroundServiceSupported()isFullScreenSupported()isGalleryTypeSupported(int)isGaussianBlurSupported()isGetAllContactsFast()isGpuSupported()isGrayscaleEnabled()isHideOverlayWindowsSupported()isHighContrastEnabled()isInCall()isInFullScreenMode()isInTransition()isInvertColorsEnabled()isJailbrokenDevice()isLargerTextEnabled()isLockOrientation()isMetaKeyDown()isMinimized()isMultiKeyMode()isMultiTouch()isNativeCommands()isNativeInAppReviewSupported()isNativeInputSupported()isNativePickerTypeSupported(int)isNativeShareSupported()isNativeTitle()isNativeVideoPlayerControlsIncluded()isNotificationSupported()isOnOffSwitchLabelsEnabled()isOpenNativeNavigationAppSupported()isPortrait()isPrintingSupported()isPureTouch()isRTL(char)isReceiveSharedContentSupported()isReduceMotionEnabled()isReduceTransparencyEnabled()isRelativeAttachmentNameResolvable()isRightMouseButtonDown()isScreenObscured()isScreenReaderEnabled()isScreenSaverDisableSupported()isScrollWheeling()isShiftKeyDown()isSimulator()isSoundPoolSupported()isSpeechRecognitionSupported()isStylusPointer()isTV()isTablet()isTextToSpeechSupported()isThirdSoftButton()isTouchScreenDevice()isVirtualKeyboardShowing()isWalletExtensionSupported()isWatch()keyPressed(int)keyReleased(int)lockOrientation(boolean)minimizeApplication()notifyPushCompletion()notifyStatusBar(String, String, String, boolean, boolean)notifyStatusBar(String, String, String, boolean, boolean, Hashtable)numAlphaLevels()numColors()onCanInstallOnHomescreen(Runnable)onEditingComplete(Component, String)openDatabaseConnections(String)openFileChooser(ActionListener, String)openGallery(ActionListener, int)openImageGallery(ActionListener)openNativeNavigationApp(String)openNativeNavigationApp(double, double)openOrCreate(String)openOrCreate(String, DatabaseConfig)openOrCreateForRekey(String)platformUsesInputMode()playBuiltinSound(String)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int[], int[])pointerReleased(int[], int[])postMessage(MessageEvent)postureChanged()print(String, String, PrintResultListener)promptInstallOnHomescreen()refreshContacts()refreshNativeTitle()registerNotificationChannel(NotificationChannelBuilder)registerPush()registerPush(String, boolean)registerPush(Hashtable, boolean)removeCompletionHandler(Media, Runnable)removeEdtErrorHandler(ActionListener)removeMessageListener(ActionListener)removePostureListener(ActionListener)removeTapjackingListener(ActionListener)removeVirtualKeyboardListener(ActionListener)removeWindowListener(ActionListener)requestFullScreen()requestIntegrityToken(String)requestNativeInAppReview(SuccessCallback)requestNotificationPermission(NotificationPermissionCallback)requestNotificationPermission(NotificationPermissionRequest, NotificationPermissionCallback)resetAttestation()restoreMinimizedApplication()restoreToBookmark()scheduleBackgroundProcessing(String, long, boolean, boolean, Runnable)scheduleBackgroundTask(Runnable)scheduleBackgroundWork(WorkRequest)scheduleLocalNotification(LocalNotification, long, int)screenshot(SuccessCallback)sendMessage(String[], String, Message)sendSMS(String, String)sendSMS(String, String, boolean)setAllowMinimizing(boolean)setAutoFoldVKBOnFormSwitch(boolean)setBadgeNumber(int)setBidiAlgorithm(boolean)setBookmark(Runnable)setBuiltinSoundsEnabled(boolean)setCommandBehavior(int)setCrashReporter(CrashReport)setDarkMode(Boolean)setDragStartPercentage(int)setEnableAsyncStackTraces(boolean)setFramerate(int)setHideOverlayWindows(boolean)setInitialWindowSizeHintPercent(Dimension)setInterval(int, Runnable)setLongPointerPressInterval(int)setMultiKeyMode(boolean)setNativeCommands(boolean)setNoSleep(boolean)setPollingFrequency(int)setPreferredBackgroundFetchInterval(int)setProjectBuildHint(String, String)setProperty(String, String)setPureTouch(boolean)setScreenSaverEnabled(boolean)setSecureScreen(boolean)setShowDuringEditBehavior(int)setShowVirtualKeyboard(boolean)setTapjackingProtection(TapjackingPolicy)setThirdSoftButton(boolean)setTimeout(int, Runnable)setTouchScreenDevice(boolean)setTransitionYield(int)setVirtualKeyboardListener(ActionListener)setWindowSize(int, int)share(String)share(String, String, String)share(String, String, String, Rectangle)share(String, String, String, Rectangle, ShareResultListener)shouldRenderSelection()shouldRenderSelection(Component)showNativePicker(int, Component, Object, Object)showNativeScreen(Object)showNotify()sizeChanged(int, int)startForegroundService(String, String, String, String, Task, ForegroundService)startRemoteControl()startSpeechRecognition(RecognitionOptions, RecognitionCallback)startThread(Runnable, String)stopEditing(Component)stopEditing(Component, Runnable)stopForegroundService(Object)stopRemoteControl()stopSpeechRecognition()subscribeToPushTopic(String)textToSpeechAvailableVoices()textToSpeechSpeak(String, TtsOptions)textToSpeechStop()unlockOrientation()unsubscribeFromPushTopic(String)updateForegroundServiceNotification(Object, String, String)vibrate(int)walletExtensionClear()walletExtensionSetAuthToken(String)walletExtensionSetPassEntries(boolean, WalletPassEntry[])walletExtensionSetRequiresAuthentication(boolean)deinitialize()getInstance()init(Object)isInitialized()")); index.put("com.codename1.ui.DynamicImage", splitMembers("addActionListener(ActionListener)animate()applyMask(Object)applyMask(Object, int, int)applyMaskAutoScale(Object)asyncLock(Image)createMask()dispose()fill(int, int)fireChangedEvent()flipHorizontally(boolean)flipVertically(boolean)getGraphics()getHeight()getImage()getImageName()getRGB()getRGB(int[])getRGBCached()getSVGDocument()getStyle()getWidth()isAnimation()isLocked()isOpaque()isSVG()lock()mirror()modifyAlpha(byte)modifyAlpha(byte, int)modifyAlphaWithTranslucency(byte)removeActionListener(ActionListener)requiresDrawImage()rotate(int)rotate180Degrees(boolean)rotate270Degrees(boolean)rotate90Degrees(boolean)scale(int, int)scaled(int, int)scaledHeight(int)scaledLargerRatio(int, int)scaledSmallerRatio(int, int)scaledWidth(int)setImageName(String)setStyle(Style)subImage(int, int, int, int, boolean)toRGB(RGBImage, int, int, int, int, int, int)unlock()setIcon(Label, DynamicImage)")); - index.put("com.codename1.ui.EditField", splitMembers("accessibilityChanged()accessibilityChanged(int)addActionListener(ActionListener)addContextMenuListener(ActionListener)addDataChangedListener(DataChangedListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)bindProperty(String, BindTarget)blocksSideSwipe()blur()clearClientProperties()commitText(String)contains(int, int)containsOrOwns(int, int)createStyleAnimation(String, int)deleteSurroundingText(int, int)drop(Component, int, int)editorChanged()finishComposing()fireEditorEvent(String, String)getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getCaretOffset()getCaretRect()getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getColumns()getComponentForm()getComponentState()getConfig()getConstraint()getCursor()getDirtyRegion()getDisabledStyle()getDocument()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getEditingState()getHeight()getHint()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getRows()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSelectionEnd()getSelectionStart()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getText()getTextLength()getTextRange(int, int)getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUndoManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()hasSelection()inputFocusGained()inputFocusLost()insertText(String)isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditableState()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSingleLineTextArea()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTextInputSupported()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)moveCaret(int, boolean)offsetAtPoint(int, int)onEditorAction(int)onKeyCommand(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)performRedo()performUndo()pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)rectForOffset(int)refreshTheme()refreshTheme(boolean)remove()removeActionListener(ActionListener)removeContextMenuListener(ActionListener)removeDataChangedListener(DataChangedListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replaceRange(int, int, String)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)selectAll()selectionRects(int, int)setAccessibilityText(String)setActionType(int)setAlwaysTensile(boolean)setBackgroundColor(int)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setColumns(int)setComponentState(Object)setComposingText(String, int)setConstraint(int)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditable(boolean)setEditableState(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setFontSizeDips(int)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHint(String)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setRows(int)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setSelectionColor(int)setSelectionRange(int, int)setShouldCalcPreferredSize(boolean)setSingleLineTextArea(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTextColor(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()startTextInput(TextInputClient, TextInputConfig)stopEditing(Runnable)stopTextInput(Object)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTextInputState(Object, TextInputState)visibleBoundsContains(int, int)")); + index.put("com.codename1.ui.EditField", splitMembers("accessibilityChanged()accessibilityChanged(int)addActionListener(ActionListener)addContextMenuListener(ActionListener)addDataChangedListener(DataChangedListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)bindProperty(String, BindTarget)blocksSideSwipe()blur()clearClientProperties()commitText(String)contains(int, int)containsOrOwns(int, int)copySelection()createStyleAnimation(String, int)cutSelection()deleteBackward()deleteSurroundingText(int, int)drop(Component, int, int)editorChanged()finishComposing()fireEditorEvent(String, String)getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getCaretOffset()getCaretRect()getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getColumns()getComponentForm()getComponentState()getConfig()getConstraint()getCursor()getDirtyRegion()getDisabledStyle()getDocument()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getEditingState()getHeight()getHint()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getRows()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSelectionEnd()getSelectionStart()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getText()getTextLength()getTextRange(int, int)getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUndoManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()hasSelection()inputFocusGained()inputFocusLost()insertText(String)isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditableState()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSingleLineTextArea()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTextInputSupported()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)moveCaret(int, boolean)offsetAtPoint(int, int)onEditorAction(int)onKeyCommand(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pasteClipboard()performRedo()performUndo()pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)rectForOffset(int)refreshTheme()refreshTheme(boolean)remove()removeActionListener(ActionListener)removeContextMenuListener(ActionListener)removeDataChangedListener(DataChangedListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replaceRange(int, int, String)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)selectAll()selectionRects(int, int)setAccessibilityText(String)setActionType(int)setAlwaysTensile(boolean)setBackgroundColor(int)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setColumns(int)setComponentState(Object)setComposingText(String, int)setConstraint(int)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditable(boolean)setEditableState(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setFontSizeDips(int)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHint(String)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setRows(int)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setSelectionColor(int)setSelectionRange(int, int)setShouldCalcPreferredSize(boolean)setSingleLineTextArea(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTextColor(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()startTextInput(TextInputClient, TextInputConfig)stopEditing(Runnable)stopTextInput(Object)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTextInputState(Object, TextInputState)visibleBoundsContains(int, int)")); index.put("com.codename1.ui.Editable", splitMembers("isEditable()isEditing()startEditingAsync()stopEditing(Runnable)")); index.put("com.codename1.ui.EncodedImage", splitMembers("addActionListener(ActionListener)animate()applyMask(Object)applyMask(Object, int, int)applyMaskAutoScale(Object)asyncLock(Image)createMask()dispose()fill(int, int)fireChangedEvent()flipHorizontally(boolean)flipVertically(boolean)getGraphics()getHeight()getImage()getImageData()getImageName()getRGB()getRGB(int[])getRGBCached()getSVGDocument()getWidth()isAnimation()isDisposed()isLocked()isOpaque()isSVG()lock()mirror()modifyAlpha(byte)modifyAlpha(byte, int)modifyAlphaWithTranslucency(byte)removeActionListener(ActionListener)requiresDrawImage()rotate(int)rotate180Degrees(boolean)rotate270Degrees(boolean)rotate90Degrees(boolean)scale(int, int)scaled(int, int)scaledEncoded(int, int)scaledHeight(int)scaledLargerRatio(int, int)scaledSmallerRatio(int, int)scaledWidth(int)setImageName(String)subImage(int, int, int, int, boolean)toRGB(RGBImage, int, int, int, int, int, int)unlock()create(String)create(byte[])create(byte[], int, int, boolean)createFromImage(Image, boolean)createFromRGB(int[], int, int, boolean)createMulti(int[], byte[][])")); + } + + private static void fillMethodIndex22(Map index) { index.put("com.codename1.ui.Font", splitMembers("addContrast(byte)charWidth(char)charsWidth(char[], int, int)derive(float, int)derive(float, int, byte)deriveLetterSpacing(float)equals(Object)getAscent()getCharset()getDescent()getFace()getHeight()getNativeFont()getPixelSize()getSize()getStyle()hashCode()isTTFNativeFont()stringWidth(String)substringWidth(String, int, int)clearBitmapCache()clearDerivedFontCache()create(String)createBitmapFont(Image, int[], int[], String)createBitmapFont(String, Image, int[], int[], String)createSystemFont(int, int, int)createTrueTypeFont(String)createTrueTypeFont(String, float)createTrueTypeFont(String, String)createTrueTypeFont(String, float, byte)getBitmapFont(String)getDefaultFont()isBitmapFontEnabled()isCreationByStringSupported()isNativeFontSchemeSupported()isTrueTypeFileSupported()setBitmapFontEnabled(boolean)setDefaultFont(Font)")); index.put("com.codename1.ui.FontImage", splitMembers("addActionListener(ActionListener)animate()applyMask(Object)applyMask(Object, int, int)applyMaskAutoScale(Object)asyncLock(Image)createMask()dispose()fill(int, int)fireChangedEvent()flipHorizontally(boolean)flipVertically(boolean)getFont()getGraphics()getHeight()getImage()getImageName()getPadding()getRGB()getRGB(int[])getRGBCached()getSVGDocument()getText()getWidth()isAnimation()isLocked()isOpaque()isSVG()lock()mirror()modifyAlpha(byte)modifyAlpha(byte, int)modifyAlphaWithTranslucency(byte)removeActionListener(ActionListener)requiresDrawImage()rotate(int)rotate180Degrees(boolean)rotate270Degrees(boolean)rotate90Degrees(boolean)rotateAnimation()scale(int, int)scaled(int, int)scaledHeight(int)scaledLargerRatio(int, int)scaledSmallerRatio(int, int)scaledWidth(int)setBgTransparency(int)setFgAlpha(int)setImageName(String)setPadding(int)subImage(int, int, int, int, boolean)toEncodedImage()toImage()toRGB(RGBImage, int, int, int, int, int, int)unlock()create(String, Style)create(String, Style, Font)createFixed(String, Font, int, int, int)createFixed(String, Font, int, int, int, int)createMaterial(char, Style)createMaterial(char, Style, float)createMaterial(char, String, float)createSFOrMaterial(char, Style, float)getDefaultPadding()getDefaultSize()getMaterialDesignFont()setDefaultPadding(int)setDefaultSize(float)setFontIcon(SpanButton, Font, char)setFontIcon(Label, Font, char)setFontIcon(MultiButton, Font, char, float)setFontIcon(SpanButton, Font, char, float)setFontIcon(SpanLabel, Font, char, float)setFontIcon(Label, Font, char, float)setFontIcon(Label, Font, char[], float)setFontIcon(Command, Font, char, String, float)setIcon(IconHolder, char, float)setIcon(IconHolder, Font, char, float)setIcon(IconHolder, Font, char[], float)setMaterialIcon(MultiButton, char)setMaterialIcon(SpanButton, char)setMaterialIcon(SpanLabel, char)setMaterialIcon(Label, char)setMaterialIcon(IconHolder, char)setMaterialIcon(MultiButton, char, float)setMaterialIcon(SpanButton, char, float)setMaterialIcon(SpanLabel, char, float)setMaterialIcon(Command, char, String)setMaterialIcon(Label, char, float)setMaterialIcon(Label, char[], float)setMaterialIcon(Component, char, float)setMaterialIcon(Component, char[], float)setMaterialIcon(Command, char, String, float)setMaterialIcon(Label, Font, char, float)")); index.put("com.codename1.ui.Form", splitMembers("accessibilityChanged()accessibilityChanged(int)add(Component)add(Image)add(String)add(Object, Component)add(Object, String)add(Object, Image)addAll(Component[]...)addCommand(Command)addCommand(Command, int)addCommandListener(ActionListener)addComponent(Component)addComponent(int, Component)addComponent(int, Object, Component)addComponentAwaitingRelease(Component)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addGameKeyListener(int, ActionListener)addKeyListener(int, ActionListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addOrientationListener(ActionListener)addPasteListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addShowListener(ActionListener)addSizeChangedListener(ActionListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animateHierarchy(int)animateHierarchyAndWait(int)animateHierarchyFade(int, int)animateHierarchyFadeAndWait(int, int)animateLayout(int)animateLayoutAndWait(int)animateLayoutFade(int, int)animateLayoutFadeAndWait(int, int)animateUnlayout(int, int, Runnable)animateUnlayoutAndWait(int, int)announceForAccessibility(String)applyRTL(boolean)bindProperty(String, BindTarget)blocksSideSwipe()checkPopGuard(PopReason)clearClientProperties()clearComponentsAwaitingRelease()contains(Component)contains(int, int)containsOrOwns(int, int)createAnimateHierarchy(int)createAnimateHierarchyFade(int, int)createAnimateLayout(int)createAnimateLayoutFade(int, int)createAnimateLayoutFadeAndWait(int, int)createAnimateUnlayout(int, int, Runnable)createReplaceTransition(Component, Component, Transition)createStyleAnimation(String, int)deregisterAnimated(Animation)dispatchCommand(Command, ActionEvent)dispatchPaste(ActionEvent)drop(Component, int, int)findCurrentlyEditingComponent()findDropTargetAt(int, int)findFirstFocusable()findNextFocusHorizontal(boolean)findNextFocusVertical(boolean)flushReplace()forceRevalidate()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBackCommand()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getChildrenAsList(boolean)getClearCommand()getClientProperty(String)getClosestComponentTo(int, int)getCloudBoundProperty()getCloudDestinationProperty()getCommand(int)getCommandCount()getComponentAt(int)getComponentAt(int, int)getComponentCount()getComponentForm()getComponentIndex(Component)getComponentState()getContentPane()getCurrentInputDevice()getCursor()getDefaultCommand()getDirtyRegion()getDisabledStyle()getDragRegionStatus(int, int)getDragTransparency()getDraggedx()getDraggedy()getEditOnShow()getEditingDelegate()getFocused()getFormLayeredPane(Class, boolean)getGlassPane()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getInvisibleAreaUnderVKB()getLabelForComponent()getLayeredPane()getLayeredPane(Class, boolean)getLayeredPane(Class, int)getLayout()getLayoutHeight()getLayoutWidth()getLeadComponent()getLeadParent()getMenuBar()getMenuStyle()getName()getNativeOverlay()getNextComponent(Component)getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPopGuard()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPreviousComponent(Component)getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getResponderAt(int, int)getSafeArea()getSafeAreaRoot()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollIncrement()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getSoftButton(int)getSoftButtonCount()getSourceCommand()getStyle()getTabIndex()getTabIterator(Component)getTensileLength()getTextSelection()getTextSelectionSupport()getTintColor()getTitle()getTitleArea()getTitleComponent()getTitleStyle()getToolbar()getTooltip()getTransitionInAnimator()getTransitionOutAnimator()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()grabAnimationLock()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()hasMedia()invalidate()isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isCyclicFocus()isDragRegion(int, int)isDraggable()isDropTarget()isEditable()isEditing()isEnableCursors()isEnabled()isFlatten()isFocusScrolling()isFocusable()isFormBottomPaddingEditingMode()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isMinimizeOnBack()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isSafeArea()isSafeAreaRoot()isScrollVisible()isScrollable()isScrollableX()isScrollableY()isSingleFocusMode()isSmoothScrolling()isSnapToGrid()isSurface()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()iterator()iterator(boolean)keyPressed(int)keyReleased(int)keyRepeated(int)layoutContainer()longPointerPress(int, int)morph(Component, Component, int, Runnable)morphAndWait(Component, Component, int)paint(Graphics)paintBackground(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)registerAnimated(Animation)releaseAnimationLock()remove()removeAll()removeAllCommands()removeAllShowListeners()removeCommand(Command)removeCommandListener(ActionListener)removeComponent(Component)removeComponentAwaitingRelease(Component)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeGameKeyListener(int, ActionListener)removeKeyListener(int, ActionListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removeOrientationListener(ActionListener)removePasteListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeShowListener(ActionListener)removeSizeChangedListener(ActionListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replace(Component, Component, Transition)replace(Component, Component, Transition, Runnable, int)replaceAndWait(Component, Component, Transition)replaceAndWait(Component, Component, Transition, int)replaceAndWait(Component, Component, Transition, boolean)requestFocus()respondsToPointerEvents()revalidate()revalidateLater()revalidateWithAnimationSafety()scrollComponentToVisible(Component)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAllowEnableLayoutOnPaint(boolean)setAlwaysTensile(boolean)setBackCommand(Command)setBackCommand(String, Image, ActionListener)setBgImage(Image)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setClearCommand(Command)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setCurrentInputDevice(VirtualInputDevice)setCursor(int)setCyclicFocus(boolean)setDefaultCommand(Command)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditOnShow(TextArea)setEditingDelegate(Editable)setEnableCursors(boolean)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusScrolling(boolean)setFocusable(boolean)setFocused(Component)setFormBottomPaddingEditingMode(boolean)setGlassPane(Painter)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLayout(Layout)setLeadComponent(Component)setMenuBar(MenuBar)setMenuCellRenderer(ListCellRenderer)setMenuTransitions(Transition, Transition)setMinimizeOnBack(boolean)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOverrideInvisibleAreaUnderVKB(int)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPopGuard(PopGuard)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setSafeArea(boolean)setSafeAreaChanged()setSafeAreaRoot(boolean)setScrollAnimationSpeed(int)setScrollIncrement(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setScrollable(boolean)setScrollableX(boolean)setScrollableY(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setSourceCommand(Command)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setTintColor(int)setTitle(String)setTitleComponent(Label)setTitleComponent(Label, Transition)setTitleStyle(Style)setToolBar(Toolbar)setToolbar(Toolbar)setTooltip(String)setTransitionInAnimator(Transition)setTransitionOutAnimator(Transition)setTraversable(boolean)setUIID(String)setUIID(String, String)setUIManager(UIManager)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)show()showBack()startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTabIndices(int)visibleBoundsContains(int, int)")); @@ -3480,9 +3700,6 @@ private static void fillMethodIndex20(Map index) { index.put("com.codename1.ui.RichTextFormat", splitMembers("")); index.put("com.codename1.ui.SelectableIconHolder", splitMembers("getDisabledIcon()getGap()getIcon()getIconFromState()getIconStyleComponent()getIconUIID()getPressedIcon()getRolloverIcon()getRolloverPressedIcon()getTextPosition()setDisabledIcon(Image)setFontIcon(Font, char, float)setGap(int)setIcon(Image)setIconUIID(String)setMaterialIcon(char, float)setPressedIcon(Image)setRolloverIcon(Image)setRolloverPressedIcon(Image)setTextPosition(int)")); index.put("com.codename1.ui.Sheet", splitMembers("accessibilityChanged()accessibilityChanged(int)add(Component)add(Image)add(String)add(Object, Component)add(Object, String)add(Object, Image)addAll(Component[]...)addBackListener(ActionListener)addCloseListener(ActionListener)addComponent(Component)addComponent(int, Component)addComponent(int, Object, Component)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animateHierarchy(int)animateHierarchyAndWait(int)animateHierarchyFade(int, int)animateHierarchyFadeAndWait(int, int)animateLayout(int)animateLayoutAndWait(int)animateLayoutFade(int, int)animateLayoutFadeAndWait(int, int)animateUnlayout(int, int, Runnable)animateUnlayoutAndWait(int, int)announceForAccessibility(String)applyRTL(boolean)back()back(int)bindProperty(String, BindTarget)blocksSideSwipe()clearClientProperties()contains(Component)contains(int, int)containsOrOwns(int, int)createAnimateHierarchy(int)createAnimateHierarchyFade(int, int)createAnimateLayout(int)createAnimateLayoutFade(int, int)createAnimateLayoutFadeAndWait(int, int)createAnimateUnlayout(int, int, Runnable)createReplaceTransition(Component, Component, Transition)createStyleAnimation(String, int)drop(Component, int, int)findDropTargetAt(int, int)findFirstFocusable()finish(Object)flushReplace()forceRevalidate()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getChildrenAsList(boolean)getClientProperty(String)getClosestComponentTo(int, int)getCloudBoundProperty()getCloudDestinationProperty()getCommandsContainer()getComponentAt(int)getComponentAt(int, int)getComponentCount()getComponentForm()getComponentIndex(Component)getComponentState()getContentPane()getCursor()getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLayout()getLayoutHeight()getLayoutWidth()getLeadComponent()getLeadParent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getParentSheet()getPosition()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getResponderAt(int, int)getSafeAreaRoot()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollIncrement()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getTextSelectionSupport()getTitle()getTitleComponent()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()hideBackButton()invalidate()isAllowClose()isAlwaysTensile()isAncestorSheetOf(Sheet)isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isSafeArea()isSafeAreaRoot()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isSurface()isSwipeToDismissEnabled()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()iterator()iterator(boolean)keyPressed(int)keyReleased(int)keyRepeated(int)layoutContainer()longPointerPress(int, int)morph(Component, Component, int, Runnable)morphAndWait(Component, Component, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)remove()removeAll()removeBackListener(ActionListener)removeCloseListener(ActionListener)removeComponent(Component)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replace(Component, Component, Transition)replace(Component, Component, Transition, Runnable, int)replaceAndWait(Component, Component, Transition)replaceAndWait(Component, Component, Transition, int)replaceAndWait(Component, Component, Transition, boolean)requestFocus()respondsToPointerEvents()revalidate()revalidateLater()revalidateWithAnimationSafety()scrollComponentToVisible(Component)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAllowClose(boolean)setAlwaysTensile(boolean)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLayout(Layout)setLeadComponent(Component)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPosition(String)setPosition(String, String)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setSafeArea(boolean)setSafeAreaRoot(boolean)setScrollAnimationSpeed(int)setScrollIncrement(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setScrollable(boolean)setScrollableX(boolean)setScrollableY(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setSwipeToDismissEnabled(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setTitle(String)setTitleComponent(Component)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUIManager(UIManager)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)show()show(int)showBackButton()showForResult()showForResult(int)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTabIndices(int)visibleBoundsContains(int, int)findContainingSheet(Component)getCurrentSheet()isSheetVisibleAt(int, int)")); - } - - private static void fillMethodIndex21(Map index) { index.put("com.codename1.ui.SideMenuBar", splitMembers("accessibilityChanged()accessibilityChanged(int)actionPerformed(ActionEvent)add(Component)add(Image)add(String)add(Object, Component)add(Object, String)add(Object, Image)addAll(Component[]...)addCommand(Command)addComponent(Component)addComponent(int, Component)addComponent(int, Object, Component)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animateHierarchy(int)animateHierarchyAndWait(int)animateHierarchyFade(int, int)animateHierarchyFadeAndWait(int, int)animateLayout(int)animateLayoutAndWait(int)animateLayoutFade(int, int)animateLayoutFadeAndWait(int, int)animateUnlayout(int, int, Runnable)animateUnlayoutAndWait(int, int)announceForAccessibility(String)applyRTL(boolean)bindProperty(String, BindTarget)blocksSideSwipe()clearClientProperties()closeMenu()contains(Component)contains(int, int)containsOrOwns(int, int)createAnimateHierarchy(int)createAnimateHierarchyFade(int, int)createAnimateLayout(int)createAnimateLayoutFade(int, int)createAnimateLayoutFadeAndWait(int, int)createAnimateUnlayout(int, int, Runnable)createReplaceTransition(Component, Component, Transition)createStyleAnimation(String, int)drop(Component, int, int)findCommandComponent(Command)findDropTargetAt(int, int)findFirstFocusable()flushReplace()forceRevalidate()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBackCommand()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getChildrenAsList(boolean)getClearCommand()getClientProperty(String)getClosestComponentTo(int, int)getCloudBoundProperty()getCloudDestinationProperty()getCommand(int)getCommandBehavior()getCommandCount()getComponentAt(int)getComponentAt(int, int)getComponentCount()getComponentForm()getComponentIndex(Component)getComponentState()getCursor()getDefaultCommand()getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLayout()getLayoutHeight()getLayoutWidth()getLeadComponent()getLeadParent()getMenuStyle()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getParentForm()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getResponderAt(int, int)getSafeAreaRoot()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollIncrement()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommand()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()handlesKeycode(int)hasFixedPreferredSize()hasFocus()invalidate()isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isMenuOpen()isMenuShowing()isMinimizeOnBack()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isSafeArea()isSafeAreaRoot()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isSurface()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()iterator()iterator(boolean)keyPressed(int)keyReleased(int)keyRepeated(int)layoutContainer()longPointerPress(int, int)morph(Component, Component, int, Runnable)morphAndWait(Component, Component, int)openMenu(String)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)remove()removeAll()removeComponent(Component)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeEmptySoftbuttons()removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replace(Component, Component, Transition)replace(Component, Component, Transition, Runnable, int)replaceAndWait(Component, Component, Transition)replaceAndWait(Component, Component, Transition, int)replaceAndWait(Component, Component, Transition, boolean)requestFocus()respondsToPointerEvents()revalidate()revalidateLater()revalidateWithAnimationSafety()scrollComponentToVisible(Component)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlwaysTensile(boolean)setBackCommand(Command)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setClearCommand(Command)setCloudBoundProperty(String)setCloudDestinationProperty(String)setCommandUIID(Command, String)setComponentState(Object)setCursor(int)setDefaultCommand(Command)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLayout(Layout)setLeadComponent(Component)setMenuCellRenderer(ListCellRenderer)setMinimizeOnBack(boolean)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setSafeArea(boolean)setSafeAreaRoot(boolean)setScrollAnimationSpeed(int)setScrollIncrement(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setScrollable(boolean)setScrollableX(boolean)setScrollableY(boolean)setSelectCommand(Command)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setTooltip(String)setTransitions(Transition, Transition)setTraversable(boolean)setUIID(String)setUIID(String, String)setUIManager(UIManager)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)showMenu()startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTabIndices(int)visibleBoundsContains(int, int)closeCurrentMenu()closeCurrentMenu(Runnable)isShowing()")); index.put("com.codename1.ui.Slider", splitMembers("accessibilityChanged()accessibilityChanged(int)addActionListener(ActionListener)addContextMenuListener(ActionListener)addDataChangedListener(DataChangedListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)bindProperty(String, BindTarget)blocksSideSwipe()clearClientProperties()contains(int, int)containsOrOwns(int, int)createStyleAnimation(String, int)deinitialize()drop(Component, int, int)getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAlignment()getAllStyles()getAnimationManager()getBadgeStyleComponent()getBadgeText()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getComponentForm()getComponentState()getCursor()getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getFontIcon()getFontIconSize()getGap()getHeight()getIcon()getIconFont()getIconStyleComponent()getIconUIID()getIncrements()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getMask()getMaskName()getMaskedIcon()getMaterialIcon()getMaterialIconSize()getMaxAutoSize()getMaxValue()getMinAutoSize()getMinValue()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getProgress()getProgress(ActionEvent)getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getShiftMillimeters()getShiftMillimetersF()getShiftText()getSideGap()getSliderEmptySelectedStyle()getSliderEmptyUnselectedStyle()getSliderFullSelectedStyle()getSliderFullUnselectedStyle()getStringWidth(Font)getStyle()getTabIndex()getTensileLength()getText()getTextPosition()getTextSelectionSupport()getThumbImage()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVerticalAlignment()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()initComponent()isAlwaysTensile()isAutoSizeMode()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isEndsWith3Points()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isInfinite()isLegacyRenderer()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRenderPercentageOnTop()isRenderValueOnTop()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isShouldLocalize()isShowEvenIfBlank()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTextSelectionEnabled()isTickerEnabled()isTickerRunning()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVertical()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)remove()removeActionListener(ActionListener)removeContextMenuListener(ActionListener)removeDataChangedListener(DataChangedListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlignment(int)setAlwaysTensile(boolean)setAutoSizeMode(boolean)setBadgeText(String)setBadgeUIID(String)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditable(boolean)setEditingDelegate(Editable)setEnabled(boolean)setEndsWith3Points(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setFontIcon(char)setFontIcon(Font, char)setFontIcon(Font, char, float)setGap(int)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIcon(Image)setIconUIID(String)setIgnorePointerEvents(boolean)setIncrements(int)setInfinite(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLegacyRenderer(boolean)setMask(Object)setMaskName(String)setMaterialIcon(char)setMaterialIcon(char, float)setMaxAutoSize(float)setMaxValue(int)setMinAutoSize(float)setMinValue(int)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setProgress(int)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRenderPercentageOnTop(boolean)setRenderValueOnTop(boolean)setRippleEffect(boolean)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShiftMillimeters(float)setShiftMillimeters(int)setShiftText(int)setShouldCalcPreferredSize(boolean)setShouldLocalize(boolean)setShowEvenIfBlank(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTextPosition(int)setTextSelectionEnabled(boolean)setThumbImage(Image)setTickerEnabled(boolean)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVertical(boolean)setVerticalAlignment(int)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)shouldTickerStart()startEditingAsync()startTicker()startTicker(long, boolean)stopEditing(Runnable)stopTicker()stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)visibleBoundsContains(int, int)createInfinite()")); index.put("com.codename1.ui.Stroke", splitMembers("equals(Object)getCapStyle()getJoinStyle()getLineWidth()getMiterLimit()hashCode()setCapStyle(int)setJoinStyle(int)setLineWidth(float)setMiterLimit(float)setStroke(Stroke)toString()")); @@ -3509,6 +3726,9 @@ private static void fillMethodIndex21(Map index) { index.put("com.codename1.ui.UIFragment.DefaultComponentFactory", splitMembers("newComponent(Element)newConstraint(Container, Element, Component, Element)")); index.put("com.codename1.ui.URLImage", splitMembers("addActionListener(ActionListener)animate()applyMask(Object)applyMask(Object, int, int)applyMaskAutoScale(Object)asyncLock(Image)createMask()dispose()fetch()fill(int, int)fireChangedEvent()flipHorizontally(boolean)flipVertically(boolean)getGraphics()getHeight()getImage()getImageData()getImageName()getRGB()getRGB(int[])getRGBCached()getSVGDocument()getWidth()isAnimation()isDisposed()isLocked()isOpaque()isSVG()lock()mirror()modifyAlpha(byte)modifyAlpha(byte, int)modifyAlphaWithTranslucency(byte)removeActionListener(ActionListener)requiresDrawImage()rotate(int)rotate180Degrees(boolean)rotate270Degrees(boolean)rotate90Degrees(boolean)scale(int, int)scaled(int, int)scaledEncoded(int, int)scaledHeight(int)scaledLargerRatio(int, int)scaledSmallerRatio(int, int)scaledWidth(int)setImageName(String)subImage(int, int, int, int, boolean)toRGB(RGBImage, int, int, int, int, int, int)unlock()createCachedImage(String, String, Image, int)createMaskAdapter(Image)createMaskAdapter(Object)createToFileSystem(EncodedImage, String, String, ImageAdapter)createToStorage(EncodedImage, String, String)createToStorage(EncodedImage, String, String, ImageAdapter)createToStorage(EncodedImage, String, String, ImageAdapter, RequestDecorator)getDefaultRequestDecorator()getExceptionHandler()setDefaultBearerToken(String)setDefaultRequestDecorator(RequestDecorator)setExceptionHandler(ErrorCallback)")); index.put("com.codename1.ui.URLImage.ErrorCallback", splitMembers("onError(URLImage, Exception)")); + } + + private static void fillMethodIndex23(Map index) { index.put("com.codename1.ui.URLImage.ImageAdapter", splitMembers("adaptImage(EncodedImage, EncodedImage)isAsyncAdapter()")); index.put("com.codename1.ui.URLImage.RequestDecorator", splitMembers("decorate(ConnectionRequest)")); index.put("com.codename1.ui.VirtualInputDevice", splitMembers("")); @@ -3546,13 +3766,10 @@ private static void fillMethodIndex21(Map index) { index.put("com.codename1.ui.css.CSSThemeCompiler", splitMembers("compile(String, MutableResource, String)")); index.put("com.codename1.ui.css.CSSThemeCompiler.CSSSyntaxException", splitMembers("")); index.put("com.codename1.ui.editor.CodePureEditor", splitMembers("cmd(String, String)getView()query(String, String)")); - index.put("com.codename1.ui.editor.CodeView", splitMembers("accessibilityChanged()accessibilityChanged(int)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)bindProperty(String, BindTarget)blocksSideSwipe()blur()clearClientProperties()commitText(String)contains(int, int)containsOrOwns(int, int)createStyleAnimation(String, int)deleteSurroundingText(int, int)drop(Component, int, int)finishComposing()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getCaretOffset()getCaretRect()getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getComponentForm()getComponentState()getConfig()getCursor()getDirtyRegion()getDisabledStyle()getDocument()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getEditingState()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLanguage()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSelectionEnd()getSelectionStart()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getText()getTextLength()getTextRange(int, int)getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUndoManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()hasSelection()inputFocusGained()inputFocusLost()insertText(String)isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditableState()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)moveCaret(int, boolean)offsetAtPoint(int, int)onEditorAction(int)onKeyCommand(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)performRedo()performUndo()pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)rectForOffset(int)refreshTheme()refreshTheme(boolean)remove()removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replaceRange(int, int, String)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)selectAll()selectionRects(int, int)setAccessibilityText(String)setAlwaysTensile(boolean)setBackgroundColor(int)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setCompletionEnabled(boolean)setComponentState(Object)setComposingText(String, int)setCursor(int)setDiagnostics(List)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditableState(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setFontSizeDips(int)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLanguage(String)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setSelectionColor(int)setSelectionRange(int, int)setShouldCalcPreferredSize(boolean)setShowLineNumbers(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTabSize(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTextColor(int)setTheme(String)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)showCompletions(int, List)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)visibleBoundsContains(int, int)")); - } - - private static void fillMethodIndex22(Map index) { + index.put("com.codename1.ui.editor.CodeView", splitMembers("accessibilityChanged()accessibilityChanged(int)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)bindProperty(String, BindTarget)blocksSideSwipe()blur()clearClientProperties()commitText(String)contains(int, int)containsOrOwns(int, int)copySelection()createStyleAnimation(String, int)cutSelection()deleteBackward()deleteSurroundingText(int, int)drop(Component, int, int)finishComposing()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getCaretOffset()getCaretRect()getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getComponentForm()getComponentState()getConfig()getCursor()getDirtyRegion()getDisabledStyle()getDocument()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getEditingState()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLanguage()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSelectionEnd()getSelectionStart()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getText()getTextLength()getTextRange(int, int)getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUndoManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()hasSelection()inputFocusGained()inputFocusLost()insertText(String)isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditableState()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)moveCaret(int, boolean)offsetAtPoint(int, int)onEditorAction(int)onKeyCommand(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pasteClipboard()performRedo()performUndo()pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)rectForOffset(int)refreshTheme()refreshTheme(boolean)remove()removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replaceRange(int, int, String)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)selectAll()selectionRects(int, int)setAccessibilityText(String)setAlwaysTensile(boolean)setBackgroundColor(int)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setCompletionEnabled(boolean)setComponentState(Object)setComposingText(String, int)setCursor(int)setDiagnostics(List)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditableState(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setFontSizeDips(int)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLanguage(String)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setProtectedRegionMarkers(String, String)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setSelectionColor(int)setSelectionRange(int, int)setShouldCalcPreferredSize(boolean)setShowLineNumbers(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTabSize(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTextColor(int)setTheme(String)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)showCompletions(int, List)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)visibleBoundsContains(int, int)")); index.put("com.codename1.ui.editor.EditorDocument", splitMembers("charAt(int)clamp(int)columnOfOffset(int)delete(int, int)getLineCount()getLineEnd(int)getLineStart(int)getLineText(int)getText()insert(int, String)length()lineOfOffset(int)setText(String)substring(int, int)normalizeText(String)")); index.put("com.codename1.ui.editor.EditorHost", splitMembers("editorChanged()fireEditorEvent(String, String)isTextInputSupported()startTextInput(TextInputClient, TextInputConfig)stopTextInput(Object)updateTextInputState(Object, TextInputState)")); - index.put("com.codename1.ui.editor.EditorView", splitMembers("accessibilityChanged()accessibilityChanged(int)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)bindProperty(String, BindTarget)blocksSideSwipe()blur()clearClientProperties()commitText(String)contains(int, int)containsOrOwns(int, int)createStyleAnimation(String, int)deleteSurroundingText(int, int)drop(Component, int, int)finishComposing()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getCaretOffset()getCaretRect()getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getComponentForm()getComponentState()getConfig()getCursor()getDirtyRegion()getDisabledStyle()getDocument()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getEditingState()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSelectionEnd()getSelectionStart()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getText()getTextLength()getTextRange(int, int)getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUndoManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()hasSelection()inputFocusGained()inputFocusLost()insertText(String)isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditableState()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)moveCaret(int, boolean)offsetAtPoint(int, int)onEditorAction(int)onKeyCommand(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)performRedo()performUndo()pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)rectForOffset(int)refreshTheme()refreshTheme(boolean)remove()removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replaceRange(int, int, String)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)selectAll()selectionRects(int, int)setAccessibilityText(String)setAlwaysTensile(boolean)setBackgroundColor(int)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setComposingText(String, int)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditableState(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setFontSizeDips(int)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setSelectionColor(int)setSelectionRange(int, int)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTextColor(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)visibleBoundsContains(int, int)")); + index.put("com.codename1.ui.editor.EditorView", splitMembers("accessibilityChanged()accessibilityChanged(int)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)bindProperty(String, BindTarget)blocksSideSwipe()blur()clearClientProperties()commitText(String)contains(int, int)containsOrOwns(int, int)copySelection()createStyleAnimation(String, int)cutSelection()deleteBackward()deleteSurroundingText(int, int)drop(Component, int, int)finishComposing()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getCaretOffset()getCaretRect()getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getComponentForm()getComponentState()getConfig()getCursor()getDirtyRegion()getDisabledStyle()getDocument()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getEditingState()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSelectionEnd()getSelectionStart()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getText()getTextLength()getTextRange(int, int)getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUndoManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()hasSelection()inputFocusGained()inputFocusLost()insertText(String)isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditableState()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)moveCaret(int, boolean)offsetAtPoint(int, int)onEditorAction(int)onKeyCommand(int, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pasteClipboard()performRedo()performUndo()pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)rectForOffset(int)refreshTheme()refreshTheme(boolean)remove()removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replaceRange(int, int, String)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)selectAll()selectionRects(int, int)setAccessibilityText(String)setAlwaysTensile(boolean)setBackgroundColor(int)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setComposingText(String, int)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditableState(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setFontSizeDips(int)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setSelectionColor(int)setSelectionRange(int, int)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTextColor(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)visibleBoundsContains(int, int)")); index.put("com.codename1.ui.editor.HtmlImporter", splitMembers("parse(String)")); index.put("com.codename1.ui.editor.HtmlImporter.Result", splitMembers("getBlocks()getImageSources()getLinks()getStyles()getText()hasBlockContent()")); index.put("com.codename1.ui.editor.HtmlSerializer", splitMembers("serialize(EditorDocument, InlineStyles, RichBlocks, List, List)")); @@ -3567,7 +3784,7 @@ private static void fillMethodIndex22(Map index) { index.put("com.codename1.ui.editor.RichRunPainter", splitMembers("fontFor(int, boolean, boolean)getBaseSizePx()paintRun(Graphics, String, TextStyle, Font, int, int, int)runFont(int, TextStyle)runPx(int, TextStyle)setBaseFont(Font)setBaseSizePx(int)setTextColor(int)headingScale(int)isHeading(int)sizeLevelScale(int)")); index.put("com.codename1.ui.editor.RichTextImporter", splitMembers("convert(String, RichTextFormat, RichTextFormat)fromHtml(String, RichTextFormat)parse(String, RichTextFormat)toHtml(String, RichTextFormat)")); index.put("com.codename1.ui.editor.RichTextSerializer", splitMembers("serialize(EditorDocument, InlineStyles, RichBlocks, List, List, RichTextFormat)")); - index.put("com.codename1.ui.editor.RichView", splitMembers("accessibilityChanged()accessibilityChanged(int)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)applyLink(String)bindProperty(String, BindTarget)blocksSideSwipe()blur()clearClientProperties()commitText(String)contains(int, int)containsOrOwns(int, int)createStyleAnimation(String, int)deleteSurroundingText(int, int)drop(Component, int, int)finishComposing()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBlocks()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getCaretOffset()getCaretRect()getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getComponentForm()getComponentState()getConfig()getCursor()getDirtyRegion()getDisabledStyle()getDocument()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getEditingState()getHeight()getImageSources()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLinkRuns()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSelectionEnd()getSelectionStart()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getText()getTextLength()getTextRange(int, int)getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUndoManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()hasSelection()importContent(String, List, List, List, List, List)indentBlocks()inputFocusGained()inputFocusLost()insertContent(String, List, List, List, List, List, boolean)insertImageObject(Image, String)insertText(String)isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditableState()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)moveCaret(int, boolean)offsetAtPoint(int, int)onEditorAction(int)onKeyCommand(int, int)outdentBlocks()paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)performRedo()performUndo()pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)queryState(String)rectForOffset(int)refreshTheme()refreshTheme(boolean)remove()removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeFormat()removeLinkStyle()removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replaceRange(int, int, String)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)selectAll()selectionRects(int, int)setAccessibilityText(String)setAlign(int)setAlwaysTensile(boolean)setBackgroundColor(int)setBlockFormat(String)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setComposingText(String, int)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditableState(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setFontSizeDips(int)setFontSizeLevel(int)setForeColor(int)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHighlight(int)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setList(int)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPlaceholder(String)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setSelectionColor(int)setSelectionRange(int, int)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTextColor(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()toggleBold()toggleItalic()toggleStrike()toggleUnderline()unbindProperty(String, BindTarget)visibleBoundsContains(int, int)")); + index.put("com.codename1.ui.editor.RichView", splitMembers("accessibilityChanged()accessibilityChanged(int)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()announceForAccessibility(String)applyLink(String)bindProperty(String, BindTarget)blocksSideSwipe()blur()clearClientProperties()commitText(String)contains(int, int)containsOrOwns(int, int)copySelection()createStyleAnimation(String, int)cutSelection()deleteBackward()deleteSurroundingText(int, int)drop(Component, int, int)finishComposing()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBlocks()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getCaretOffset()getCaretRect()getClientProperty(String)getCloudBoundProperty()getCloudDestinationProperty()getComponentForm()getComponentState()getConfig()getCursor()getDirtyRegion()getDisabledStyle()getDocument()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getEditingState()getHeight()getImageSources()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLinkRuns()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSelectionEnd()getSelectionStart()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getText()getTextLength()getTextRange(int, int)getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUndoManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()hasSelection()importContent(String, List, List, List, List, List)indentBlocks()inputFocusGained()inputFocusLost()insertContent(String, List, List, List, List, List, boolean)insertImageObject(Image, String)insertText(String)isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditableState()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()keyPressed(int)keyReleased(int)keyRepeated(int)longPointerPress(int, int)moveCaret(int, boolean)offsetAtPoint(int, int)onEditorAction(int)onKeyCommand(int, int)outdentBlocks()paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pasteClipboard()performRedo()performUndo()pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)queryState(String)rectForOffset(int)refreshTheme()refreshTheme(boolean)remove()removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeFormat()removeLinkStyle()removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replaceRange(int, int, String)requestFocus()respondsToPointerEvents()scrollRectToVisible(int, int, int, int, Component)selectAll()selectionRects(int, int)setAccessibilityText(String)setAlign(int)setAlwaysTensile(boolean)setBackgroundColor(int)setBlockFormat(String)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setComposingText(String, int)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditableState(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setFontSizeDips(int)setFontSizeLevel(int)setForeColor(int)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHighlight(int)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setList(int)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPlaceholder(String)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setScrollAnimationSpeed(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setSelectCommandText(String)setSelectedStyle(Style)setSelectionColor(int)setSelectionRange(int, int)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setText(String)setTextColor(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()toggleBold()toggleItalic()toggleStrike()toggleUnderline()unbindProperty(String, BindTarget)visibleBoundsContains(int, int)")); index.put("com.codename1.ui.editor.SyntaxHighlightResult", splitMembers("")); index.put("com.codename1.ui.editor.SyntaxHighlighter", splitMembers("tokenize(String, int)")); index.put("com.codename1.ui.editor.SyntaxToken", splitMembers("")); @@ -3576,6 +3793,9 @@ private static void fillMethodIndex22(Map index) { index.put("com.codename1.ui.editor.Tokenizer", splitMembers("tokenize(String, int)")); index.put("com.codename1.ui.editor.UndoManager", splitMembers("breakRun()canRedo()canUndo()clear()record(int, String, String)redo(EditorDocument)undo(EditorDocument)")); index.put("com.codename1.ui.events.ActionEvent", splitMembers("consume()getActualComponent()getCommand()getComponent()getDraggedComponent()getDropTarget()getEventType()getKeyEvent()getPointerEvent()getProgress()getSource()getX()getY()isConsumed()isLongEvent()isPointerPressedDuringDrag()setPointerEvent(PointerEvent)setPointerPressedDuringDrag(boolean)")); + } + + private static void fillMethodIndex24(Map index) { index.put("com.codename1.ui.events.ActionEvent.Type", splitMembers("")); index.put("com.codename1.ui.events.ActionListener", splitMembers("actionPerformed(ActionEvent)")); index.put("com.codename1.ui.events.ActionSource", splitMembers("addActionListener(ActionListener)removeActionListener(ActionListener)")); @@ -3614,9 +3834,6 @@ private static void fillMethodIndex22(Map index) { index.put("com.codename1.ui.html.HTMLParser", splitMembers("addCharEntitiesRange(String[], int)addCharEntity(String, int)isCaseSensitive()setCaseSensitive(boolean)setIncludeWhitespacesBetweenTags(boolean)setParserCallback(ParserCallback)")); index.put("com.codename1.ui.html.HTMLUtils", splitMembers("convertCharEntity(String, boolean, Hashtable)convertHTMLCharEntity(String)convertXMLCharEntity(String)encodeString(String)")); index.put("com.codename1.ui.html.IOCallback", splitMembers("")); - } - - private static void fillMethodIndex23(Map index) { index.put("com.codename1.ui.layouts.BorderLayout", splitMembers("addLayoutComponent(Object, Component, Container)cloneConstraint(Object)defineLandscapeSwap(String, String)equals(Object)getCenter()getCenterBehavior()getComponentConstraint(Component)getEast()getLandscapeSwap(String)getNorth()getOverlay()getPreferredSize(Container)getSouth()getWest()hashCode()isAbsoluteCenter()isConstraintTracking()isOverlapSupported()isScaleEdges()layoutContainer(Container)obscuresPotential(Container)overridesTabIndices(Container)removeLayoutComponent(Component)setAbsoluteCenter(boolean)setCenterBehavior(int)setScaleEdges(boolean)toString()updateTabIndices(Container, int)absolute()center()center(Component)centerAbsolute(Component)centerAbsoluteEastWest(Component, Component, Component)centerCenter(Component)centerCenterEastWest(Component, Component, Component)centerEastWest(Component, Component, Component)centerTotalBelow(Component)centerTotalBelowEastWest(Component, Component, Component)east(Component)north(Component)south(Component)totalBelow()west(Component)")); index.put("com.codename1.ui.layouts.BoxLayout", splitMembers("addLayoutComponent(Object, Component, Container)cloneConstraint(Object)equals(Object)getAlign()getAxis()getComponentConstraint(Component)getPreferredSize(Container)hashCode()isConstraintTracking()isOverlapSupported()layoutContainer(Container)obscuresPotential(Container)overridesTabIndices(Container)removeLayoutComponent(Component)setAlign(int)toString()updateTabIndices(Container, int)encloseX(Component[]...)encloseXCenter(Component[]...)encloseXNoGrow(Component[]...)encloseXRight(Component[]...)encloseY(Component[]...)encloseYBottom(Component[]...)encloseYBottomLast(Component[]...)encloseYCenter(Component[]...)x()xCenter()xRight()y()yBottom()yCenter()yLast()")); index.put("com.codename1.ui.layouts.CoordinateLayout", splitMembers("addLayoutComponent(Object, Component, Container)cloneConstraint(Object)equals(Object)getComponentConstraint(Component)getPreferredSize(Container)hashCode()isConstraintTracking()isOverlapSupported()layoutContainer(Container)obscuresPotential(Container)overridesTabIndices(Container)removeLayoutComponent(Component)updateTabIndices(Container, int)")); @@ -3643,6 +3860,9 @@ private static void fillMethodIndex23(Map index) { index.put("com.codename1.ui.layouts.mig.LayoutCallback", splitMembers("correctBounds(ComponentWrapper)getPosition(ComponentWrapper)getSize(ComponentWrapper)")); index.put("com.codename1.ui.layouts.mig.LayoutUtil", splitMembers("getDesignTimeEmptySize()getGlobalDebugMillis()getSerializedObject(Object)getSizeSafe(int[], int)getVersion()isDesignTime(ContainerWrapper)isLeftToRight(LC, ContainerWrapper)setDesignTime(ContainerWrapper, boolean)setDesignTimeEmptySize(int)setGlobalDebugMillis(int)setSerializedObject(Object, Object)")); index.put("com.codename1.ui.layouts.mig.LinkHandler", splitMembers("clearBounds(Object, String)clearWeakReferencesNow()getValue(Object, String, int)setBounds(Object, String, int, int, int, int)")); + } + + private static void fillMethodIndex25(Map index) { index.put("com.codename1.ui.layouts.mig.MigLayout", splitMembers("addLayoutCallback(LayoutCallback)addLayoutComponent(Component, Object)addLayoutComponent(Object, Component, Container)cloneConstraint(Object)equals(Object)getColumnConstraints()getComponentConstraint(Component)getComponentConstraints(Component)getConstraintMap()getLayoutAlignmentX(Container)getLayoutAlignmentY(Container)getLayoutConstraints()getPreferredSize(Container)getRowConstraints()hashCode()invalidateLayout(Container)isConstraintTracking()isManagingComponent(Component)isOverlapSupported()layoutContainer(Container)maximumLayoutSize(Container)minimumLayoutSize(Container)obscuresPotential(Container)overridesTabIndices(Container)preferredLayoutSize(Container)removeLayoutCallback(LayoutCallback)removeLayoutComponent(Component)setColumnConstraints(Object)setComponentConstraints(Component, Object)setConstraintMap(Map)setLayoutConstraints(Object)setRowConstraints(Object)updateTabIndices(Container, int)findType(Class, Component)")); index.put("com.codename1.ui.layouts.mig.PlatformDefaults", splitMembers("invalidate()getButtonOrder()getCurrentPlatform()getDefaultDPI()getDefaultHorizontalUnit()getDefaultRowAlignmentBaseline()getDefaultVerticalUnit()getDefaultVisualPadding(String)getDialogInsets(int)getGapProvider()getGridGapX()getGridGapY()getHorizontalScaleFactor()getLabelAlignPercentage()getLogicalPixelBase()getMinimumButtonWidth()getModCount()getPanelInsets(int)getPlatform()getPlatformDPI(int)getUnitValueX(String)getUnitValueY(String)getVerticalScaleFactor()setButtonOrder(String)setDefaultDPI(Integer)setDefaultHorizontalUnit(int)setDefaultRowAlignmentBaseline(boolean)setDefaultVerticalUnit(int)setDefaultVisualPadding(String, int[])setDialogInsets(UnitValue, UnitValue, UnitValue, UnitValue)setGapProvider(InCellGapProvider)setGridCellGap(UnitValue, UnitValue)setHorizontalScaleFactor(Float)setIndentGap(UnitValue, UnitValue)setLogicalPixelBase(int)setMinimumButtonWidth(UnitValue)setPanelInsets(UnitValue, UnitValue, UnitValue, UnitValue)setParagraphGap(UnitValue, UnitValue)setPlatform(int)setRelatedGap(UnitValue, UnitValue)setUnitValue(String[], UnitValue, UnitValue)setUnrelatedGap(UnitValue, UnitValue)setVerticalScaleFactor(Float)")); index.put("com.codename1.ui.layouts.mig.UnitConverter", splitMembers("convertToPixels(float, String, boolean, float, ContainerWrapper, ComponentWrapper)")); @@ -3681,9 +3901,6 @@ private static void fillMethodIndex23(Map index) { index.put("com.codename1.ui.plaf.StyleParser.StyleInfo", splitMembers("getAlignment()getAlignmentAsString()getBgColor()getBgImage()getBgType()getBgTypeAsString()getBorder()getFgColor()getFont()getMargin()getOpacity()getPadding()getTextDecoration()getTextDecorationAsString()getTransparency()setAlignment(int)setAlignment(String)setBgColor(String)setBgImage(String)setBgType(Integer)setBgType(String)setBorder(String)setFgColor(String)setFont(String)setFontName(String)setFontSize(String)setMargin(String)setOpacity(String)setPadding(String)setTransparency(String)toStyleString()")); index.put("com.codename1.ui.plaf.UIManager", splitMembers("addThemeProps(Hashtable)addThemeRefreshListener(ActionListener)getBundle()getComponentCustomStyle(String, String)getComponentSelectedStyle(String)getComponentStyle(String)getIconUIIDFor(String)getLookAndFeel()getResourceBundle()getThemeConstant(String, int)getThemeConstant(String, String)getThemeImageConstant(String)getThemeMaskConstant(String)getThemeName()isThemeConstant(String)isThemeConstant(String, boolean)isUseLargerTextScale()localize(String, String)parseComponentCustomStyle(Resources, String, String, String, String[]...)parseComponentSelectedStyle(Resources, String, String, String[]...)parseComponentStyle(Resources, String, String, String[]...)refreshTheme()removeThemeRefreshListener(ActionListener)setBundle(Map)setComponentSelectedStyle(String, Style)setComponentStyle(String, Style)setComponentStyle(String, Style, String)setLookAndFeel(LookAndFeel)setResourceBundle(Hashtable)setThemeProps(Hashtable)setUseLargerTextScale(boolean)wasThemeInstalled()zoomFonts(float)createInstance()getInstance()initFirstTheme(String)initNamedTheme(String, String)")); index.put("com.codename1.ui.scene.Bounds", splitMembers("getDepth()getHeight()getMinX()getMinY()getMinZ()getWidth()setDepth(double)setHeight(double)setMinX(double)setMinY(double)setMinZ(double)setWidth(double)")); - } - - private static void fillMethodIndex24(Map index) { index.put("com.codename1.ui.scene.Camera", splitMembers("getTransform()")); index.put("com.codename1.ui.scene.Node", splitMembers("add(Node)addTags(String[]...)contains(int, int)findNodesWithTag(String)getBoundsInScene(Rectangle2D)getChildAt(int)getChildCount()getChildNodes()getLocalToParentTransform()getLocalToSceneTransform()getLocalToScreenTransform()getRenderer()getScene()getStyle()hasChildren()hasTag(String)isNeedsLayout()remove(Node)removeAll()removeTags(String[]...)render(Graphics)renderChildren(Graphics)setNeedsLayout(boolean)setRenderAsImage(boolean)setRenderer(NodePainter)setStyle(Style)")); index.put("com.codename1.ui.scene.NodePainter", splitMembers("paint(Graphics, Rectangle, Node)")); @@ -3710,6 +3927,9 @@ private static void fillMethodIndex24(Map index) { index.put("com.codename1.ui.tree.Tree", splitMembers("accessibilityChanged()accessibilityChanged(int)add(Component)add(Image)add(String)add(Object, Component)add(Object, String)add(Object, Image)addAll(Component[]...)addComponent(Component)addComponent(int, Component)addComponent(int, Object, Component)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLeafListener(ActionListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animateHierarchy(int)animateHierarchyAndWait(int)animateHierarchyFade(int, int)animateHierarchyFadeAndWait(int, int)animateLayout(int)animateLayoutAndWait(int)animateLayoutFade(int, int)animateLayoutFadeAndWait(int, int)animateUnlayout(int, int, Runnable)animateUnlayoutAndWait(int, int)announceForAccessibility(String)applyRTL(boolean)bindProperty(String, BindTarget)blocksSideSwipe()clearClientProperties()collapsePath(Object[]...)contains(Component)contains(int, int)containsOrOwns(int, int)createAnimateHierarchy(int)createAnimateHierarchyFade(int, int)createAnimateLayout(int)createAnimateLayoutFade(int, int)createAnimateLayoutFadeAndWait(int, int)createAnimateUnlayout(int, int, Runnable)createReplaceTransition(Component, Component, Transition)createStyleAnimation(String, int)drop(Component, int, int)expandPath(Object[]...)expandPath(boolean, Object[]...)findDropTargetAt(int, int)findFirstFocusable()findNodeComponent(Object)findNodeComponent(Object, Component)flushReplace()forceRevalidate()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getChildrenAsList(boolean)getClientProperty(String)getClosestComponentTo(int, int)getCloudBoundProperty()getCloudDestinationProperty()getComponentAt(int)getComponentAt(int, int)getComponentCount()getComponentForm()getComponentIndex(Component)getComponentState()getCursor()getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLayout()getLayoutHeight()getLayoutWidth()getLeadComponent()getLeadParent()getModel()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getParentComponent(Component)getParentNode(Component)getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getResponderAt(int, int)getSafeAreaRoot()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollIncrement()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedItem()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getTextSelectionSupport()getTooltip()getTreeState()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()invalidate()isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isMultilineMode()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isSafeArea()isSafeAreaRoot()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isSurface()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()iterator()iterator(boolean)keyPressed(int)keyReleased(int)keyRepeated(int)layoutContainer()longPointerPress(int, int)morph(Component, Component, int, Runnable)morphAndWait(Component, Component, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshNode(Component)refreshTheme()refreshTheme(boolean)remove()removeAll()removeComponent(Component)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLeafListener(ActionListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replace(Component, Component, Transition)replace(Component, Component, Transition, Runnable, int)replaceAndWait(Component, Component, Transition)replaceAndWait(Component, Component, Transition, int)replaceAndWait(Component, Component, Transition, boolean)requestFocus()respondsToPointerEvents()revalidate()revalidateLater()revalidateWithAnimationSafety()scrollComponentToVisible(Component)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlwaysTensile(boolean)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditingDelegate(Editable)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLayout(Layout)setLeadComponent(Component)setModel(TreeModel)setMultilineMode(boolean)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setSafeArea(boolean)setSafeAreaRoot(boolean)setScrollAnimationSpeed(int)setScrollIncrement(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setScrollable(boolean)setScrollableX(boolean)setScrollableY(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setTooltip(String)setTraversable(boolean)setTreeState(TreeState)setUIID(String)setUIID(String, String)setUIManager(UIManager)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTabIndices(int)visibleBoundsContains(int, int)setFolderIcon(Image)setFolderOpenIcon(Image)setNodeIcon(Image)")); index.put("com.codename1.ui.tree.Tree.TreeState", splitMembers("")); index.put("com.codename1.ui.tree.TreeModel", splitMembers("getChildren(Object)isLeaf(Object)")); + } + + private static void fillMethodIndex26(Map index) { index.put("com.codename1.ui.util.Effects", splitMembers("dropshadow(Image, int, float)dropshadow(Image, int, float, int, int)gaussianBlurImage(Image, float)growShrink(Component, int)isGaussianBlurSupported()reflectionImage(Image)reflectionImage(Image, float, int)reflectionImage(Image, float, int, int)squareShadow(int, int, int, float)verticalPerspective(Image, float, float, float)")); index.put("com.codename1.ui.util.EmbeddedContainer", splitMembers("accessibilityChanged()accessibilityChanged(int)add(Component)add(Image)add(String)add(Object, Component)add(Object, String)add(Object, Image)addAll(Component[]...)addComponent(Component)addComponent(int, Component)addComponent(int, Object, Component)addContextMenuListener(ActionListener)addDragFinishedListener(ActionListener)addDragOverListener(ActionListener)addDropListener(ActionListener)addFocusListener(FocusListener)addLongPressListener(ActionListener)addMouseWheelListener(ActionListener)addPointerDraggedListener(ActionListener)addPointerPressedListener(ActionListener)addPointerReleasedListener(ActionListener)addPullToRefresh(Runnable)addScrollListener(ScrollListener)addStateChangeListener(ActionListener)addStylusListener(ActionListener)animate()animateHierarchy(int)animateHierarchyAndWait(int)animateHierarchyFade(int, int)animateHierarchyFadeAndWait(int, int)animateLayout(int)animateLayoutAndWait(int)animateLayoutFade(int, int)animateLayoutFadeAndWait(int, int)animateUnlayout(int, int, Runnable)animateUnlayoutAndWait(int, int)announceForAccessibility(String)applyRTL(boolean)bindProperty(String, BindTarget)blocksSideSwipe()clearClientProperties()contains(Component)contains(int, int)containsOrOwns(int, int)createAnimateHierarchy(int)createAnimateHierarchyFade(int, int)createAnimateLayout(int)createAnimateLayoutFade(int, int)createAnimateLayoutFadeAndWait(int, int)createAnimateUnlayout(int, int, Runnable)createReplaceTransition(Component, Component, Transition)createStyleAnimation(String, int)drop(Component, int, int)findDropTargetAt(int, int)findFirstFocusable()flushReplace()forceRevalidate()getAbsoluteX()getAbsoluteY()getAccessibilityNode()getAccessibilityText()getAllStyles()getAnimationManager()getBaseline(int, int)getBaselineResizeBehavior()getBindablePropertyNames()getBindablePropertyTypes()getBottomGap()getBoundPropertyValue(String)getBounds(Rectangle)getChildrenAsList(boolean)getClientProperty(String)getClosestComponentTo(int, int)getCloudBoundProperty()getCloudDestinationProperty()getComponentAt(int)getComponentAt(int, int)getComponentCount()getComponentForm()getComponentIndex(Component)getComponentState()getCursor()getDirtyRegion()getDisabledStyle()getDragTransparency()getDraggedx()getDraggedy()getEditingDelegate()getEmbed()getHeight()getInlineAllStyles()getInlineDisabledStyles()getInlinePressedStyles()getInlineSelectedStyles()getInlineStylesTheme()getInlineUnselectedStyles()getInnerHeight()getInnerPreferredH()getInnerPreferredW()getInnerWidth()getInnerX()getInnerY()getLabelForComponent()getLayout()getLayoutHeight()getLayoutWidth()getLeadComponent()getLeadParent()getName()getNativeOverlay()getNextFocusDown()getNextFocusLeft()getNextFocusRight()getNextFocusUp()getOuterHeight()getOuterPreferredH()getOuterPreferredW()getOuterWidth()getOuterX()getOuterY()getOwner()getParent()getPreferredH()getPreferredSize()getPreferredSizeStr()getPreferredTabIndex()getPreferredW()getPressedStyle()getPropertyNames()getPropertyTypeNames()getPropertyTypes()getPropertyValue(String)getResponderAt(int, int)getSafeAreaRoot()getSameHeight()getSameWidth()getScrollAnimationSpeed()getScrollDimension()getScrollIncrement()getScrollOpacity()getScrollOpacityChangeSpeed()getScrollX()getScrollY()getScrollable()getSelectCommandText()getSelectedRect()getSelectedStyle()getSemantics()getSideGap()getStyle()getTabIndex()getTensileLength()getTextSelectionSupport()getTooltip()getUIID()getUIManager()getUnselectedStyle()getVisibleBounds(Rectangle)getWidth()getX()getY()growShrink(int)handlesInput()hasFixedPreferredSize()hasFocus()invalidate()isAlwaysTensile()isBlockLead()isCellRenderer()isChildOf(Container)isDraggable()isDropTarget()isEditable()isEditing()isEnabled()isFlatten()isFocusable()isGrabsPointerEvents()isHScrollThumbGrabbed()isHScrollThumbHover()isHidden()isHidden(boolean)isHideInLandscape()isHideInPortrait()isIgnorePointerEvents()isOpaque()isOwnedBy(Component)isPinchBlocksDragAndDrop()isRTL()isRippleEffect()isSafeArea()isSafeAreaRoot()isScrollVisible()isScrollableX()isScrollableY()isSmoothScrolling()isSnapToGrid()isSurface()isTactileTouch()isTensileDragEnabled()isTraversable()isVScrollThumbGrabbed()isVScrollThumbHover()isVisible()iterator()iterator(boolean)keyPressed(int)keyReleased(int)keyRepeated(int)layoutContainer()longPointerPress(int, int)morph(Component, Component, int, Runnable)morphAndWait(Component, Component, int)paint(Graphics)paintBackgrounds(Graphics)paintComponent(Graphics)paintComponent(Graphics, boolean)paintComponentBackground(Graphics)paintIntersectingComponentsAbove(Graphics)paintLock(boolean)paintLockRelease()paintRippleOverlay(Graphics, int, int, int)paintShadows(Graphics, int, int)pointerDragged(int, int)pointerDragged(int[], int[])pointerHover(int[], int[])pointerHoverPressed(int[], int[])pointerHoverReleased(int[], int[])pointerPressed(int, int)pointerPressed(int[], int[])pointerReleased(int, int)pointerReleased(int[], int[])putClientProperty(String, Object)refreshTheme()refreshTheme(boolean)remove()removeAll()removeComponent(Component)removeContextMenuListener(ActionListener)removeDragFinishedListener(ActionListener)removeDragOverListener(ActionListener)removeDropListener(ActionListener)removeFocusListener(FocusListener)removeLongPressListener(ActionListener)removeMouseWheelListener(ActionListener)removePointerDraggedListener(ActionListener)removePointerPressedListener(ActionListener)removePointerReleasedListener(ActionListener)removeScrollListener(ScrollListener)removeStateChangeListener(ActionListener)removeStylusListener(ActionListener)repaint()repaint(int, int, int, int)replace(Component, Component, Transition)replace(Component, Component, Transition, Runnable, int)replaceAndWait(Component, Component, Transition)replaceAndWait(Component, Component, Transition, int)replaceAndWait(Component, Component, Transition, boolean)requestFocus()respondsToPointerEvents()revalidate()revalidateLater()revalidateWithAnimationSafety()scrollComponentToVisible(Component)scrollRectToVisible(int, int, int, int, Component)setAccessibilityText(String)setAlwaysTensile(boolean)setBlockLead(boolean)setBoundPropertyValue(String, Object)setCellRenderer(boolean)setCloudBoundProperty(String)setCloudDestinationProperty(String)setComponentState(Object)setCursor(int)setDirtyRegion(Rectangle)setDisabledStyle(Style)setDragTransparency(byte)setDraggable(boolean)setDropTarget(boolean)setEditingDelegate(Editable)setEmbed(String)setEnabled(boolean)setFlatten(boolean)setFocus(boolean)setFocusable(boolean)setGrabsPointerEvents(boolean)setHandlesInput(boolean)setHeight(int)setHidden(boolean)setHidden(boolean, boolean)setHideInLandscape(boolean)setHideInPortrait(boolean)setHorizontalScrollBounds(int, int, int, int, int, int, int, int)setIgnorePointerEvents(boolean)setInlineAllStyles(String)setInlineDisabledStyles(String)setInlinePressedStyles(String)setInlineSelectedStyles(String)setInlineStylesTheme(Resources)setInlineUnselectedStyles(String)setIsScrollVisible(boolean)setLabelForComponent(Label)setLayout(Layout)setLeadComponent(Component)setName(String)setNextFocusDown(Component)setNextFocusLeft(Component)setNextFocusRight(Component)setNextFocusUp(Component)setOpaque(boolean)setOwner(Component)setPinchBlocksDragAndDrop(boolean)setPreferredH(int)setPreferredSize(Dimension)setPreferredSizeStr(String)setPreferredTabIndex(int)setPreferredW(int)setPressedStyle(Style)setPropertyValue(String, Object)setPullToRefresh(Runnable)setRTL(boolean)setRippleEffect(boolean)setSafeArea(boolean)setSafeAreaRoot(boolean)setScrollAnimationSpeed(int)setScrollIncrement(int)setScrollOpacityChangeSpeed(int)setScrollSize(Dimension)setScrollVisible(boolean)setScrollable(boolean)setScrollableX(boolean)setScrollableY(boolean)setSelectCommandText(String)setSelectedStyle(Style)setShouldCalcPreferredSize(boolean)setSize(Dimension)setSmoothScrolling(boolean)setSnapToGrid(boolean)setTabIndex(int)setTactileTouch(boolean)setTensileDragEnabled(boolean)setTensileLength(int)setTooltip(String)setTraversable(boolean)setUIID(String)setUIID(String, String)setUIManager(UIManager)setUnselectedStyle(Style)setVerticalScrollBounds(int, int, int, int, int, int, int, int)setVisible(boolean)setWidth(int)setX(int)setY(int)startEditingAsync()stopEditing(Runnable)stripMarginAndPadding()styleChanged(String, Style)toImage()toString()unbindProperty(String, BindTarget)updateTabIndices(int)visibleBoundsContains(int, int)")); index.put("com.codename1.ui.util.EventDispatcher", splitMembers("addListener(Object)fireActionEvent(ActionEvent)fireBindTargetChange(Component, String, Object, Object)fireDataChangeEvent(int, int)fireFocus(Component)fireScrollEvent(int, int, int, int)fireSelectionEvent(int, int)fireStyleChangeEvent(String, Style)getListenerCollection()getListenerVector()hasListeners()isBlocking()removeListener(Object)setBlocking(boolean)setFireStyleEventsOnNonEDT(boolean)")); @@ -3748,9 +3968,6 @@ private static void fillMethodIndex24(Map index) { index.put("com.codename1.util.EasyThread.ErrorListener", splitMembers("")); index.put("com.codename1.util.FailureCallback", splitMembers("")); index.put("com.codename1.util.LazyValue", splitMembers("")); - } - - private static void fillMethodIndex25(Map index) { index.put("com.codename1.util.MathUtil", splitMembers("")); index.put("com.codename1.util.OnComplete", splitMembers("")); index.put("com.codename1.util.RunnableWithResult", splitMembers("")); @@ -3777,6 +3994,9 @@ private static void fillMethodIndex25(Map index) { index.put("com.codename1.util.regex.StringReader", splitMembers("")); index.put("com.codename1.vr.HeadTracker", splitMembers("")); index.put("com.codename1.vr.Media360View", splitMembers("")); + } + + private static void fillMethodIndex27(Map index) { index.put("com.codename1.vr.OrientationFilter", splitMembers("")); index.put("com.codename1.vr.TextureSource", splitMembers("")); index.put("com.codename1.vr.VRCameraRig", splitMembers("")); @@ -3785,6 +4005,7 @@ private static void fillMethodIndex25(Map index) { index.put("com.codename1.vr.VRSettings", splitMembers("")); index.put("com.codename1.vr.VRView", splitMembers("")); index.put("com.codename1.wearable.WearableConnection", splitMembers("")); + index.put("com.codename1.wearable.WearableConnection.DroppedDeliveryHandler", splitMembers("")); index.put("com.codename1.wearable.WearableDataListener", splitMembers("")); index.put("com.codename1.wearable.WearableMessage", splitMembers("")); index.put("com.codename1.wearable.WearableMessageListener", splitMembers("")); @@ -3815,9 +4036,6 @@ private static void fillMethodIndex25(Map index) { index.put("java.io.FileNotFoundException", splitMembers("")); index.put("java.io.Flushable", splitMembers("")); index.put("java.io.IOException", splitMembers("")); - } - - private static void fillMethodIndex26(Map index) { index.put("java.io.InputStream", splitMembers("")); index.put("java.io.InputStreamReader", splitMembers("")); index.put("java.io.InterruptedIOException", splitMembers("")); @@ -3843,6 +4061,9 @@ private static void fillMethodIndex26(Map index) { index.put("java.lang.Character", splitMembers("")); index.put("java.lang.Class", splitMembers("")); index.put("java.lang.ClassCastException", splitMembers("")); + } + + private static void fillMethodIndex28(Map index) { index.put("java.lang.ClassLoader", splitMembers("")); index.put("java.lang.ClassNotFoundException", splitMembers("")); index.put("java.lang.CloneNotSupportedException", splitMembers("")); @@ -3882,9 +4103,6 @@ private static void fillMethodIndex26(Map index) { index.put("java.lang.SafeVarargs", splitMembers("")); index.put("java.lang.SecurityException", splitMembers("")); index.put("java.lang.Short", splitMembers("")); - } - - private static void fillMethodIndex27(Map index) { index.put("java.lang.StackTraceElement", splitMembers("")); index.put("java.lang.String", splitMembers("")); index.put("java.lang.StringBuffer", splitMembers("")); @@ -3910,6 +4128,9 @@ private static void fillMethodIndex27(Map index) { index.put("java.text.DateFormat", splitMembers("")); index.put("java.text.DateFormatSymbols", splitMembers("")); index.put("java.text.Format", splitMembers("")); + } + + private static void fillMethodIndex29(Map index) { index.put("java.text.ParseException", splitMembers("")); index.put("java.text.SimpleDateFormat", splitMembers("")); index.put("java.time.Clock", splitMembers("")); @@ -3949,9 +4170,6 @@ private static void fillMethodIndex27(Map index) { index.put("java.util.Dictionary", splitMembers("")); index.put("java.util.EmptyStackException", splitMembers("")); index.put("java.util.Enumeration", splitMembers("")); - } - - private static void fillMethodIndex28(Map index) { index.put("java.util.EventListener", splitMembers("")); index.put("java.util.HashMap", splitMembers("")); index.put("java.util.HashSet", splitMembers("")); @@ -3977,6 +4195,9 @@ private static void fillMethodIndex28(Map index) { index.put("java.util.Random", splitMembers("")); index.put("java.util.RandomAccess", splitMembers("")); index.put("java.util.Set", splitMembers("")); + } + + private static void fillMethodIndex30(Map index) { index.put("java.util.SortedMap", splitMembers("")); index.put("java.util.SortedSet", splitMembers("")); index.put("java.util.Stack", splitMembers("")); @@ -4037,6 +4258,8 @@ private static Map buildFieldIndex() { fillFieldIndex26(index); fillFieldIndex27(index); fillFieldIndex28(index); + fillFieldIndex29(index); + fillFieldIndex30(index); return index; } @@ -4122,24 +4345,31 @@ private static void fillFieldIndex1(Map index) { index.put("com.codename1.ai.language.Translator", splitMembers("")); index.put("com.codename1.ai.language.Translator.Session", splitMembers("")); index.put("com.codename1.ai.vision.Barcode", splitMembers("")); + index.put("com.codename1.ai.vision.BarcodeFormat", splitMembers("")); index.put("com.codename1.ai.vision.BarcodeScanner", splitMembers("")); + index.put("com.codename1.ai.vision.CodeScanner", splitMembers("")); + index.put("com.codename1.ai.vision.CodeScannerOptions", splitMembers("")); index.put("com.codename1.ai.vision.DocumentScanResult", splitMembers("")); index.put("com.codename1.ai.vision.DocumentScanner", splitMembers("")); index.put("com.codename1.ai.vision.Face", splitMembers("")); index.put("com.codename1.ai.vision.FaceDetector", splitMembers("")); + index.put("com.codename1.ai.vision.FaceLandmarks", splitMembers("")); index.put("com.codename1.ai.vision.ImageLabel", splitMembers("")); index.put("com.codename1.ai.vision.ImageLabeler", splitMembers("")); index.put("com.codename1.ai.vision.Pose", splitMembers("")); index.put("com.codename1.ai.vision.Pose.Landmark", splitMembers("")); index.put("com.codename1.ai.vision.PoseDetector", splitMembers("")); + index.put("com.codename1.ai.vision.PoseLandmarks", splitMembers("")); index.put("com.codename1.ai.vision.SegmentationMask", splitMembers("")); index.put("com.codename1.ai.vision.SelfieSegmenter", splitMembers("")); index.put("com.codename1.ai.vision.TextRecognitionResult", splitMembers("")); index.put("com.codename1.ai.vision.TextRecognitionResult.TextBlock", splitMembers("")); index.put("com.codename1.ai.vision.TextRecognizer", splitMembers("")); + index.put("com.codename1.ai.vision.TextScript", splitMembers("")); index.put("com.codename1.ai.vision.VisionAnalyzer", splitMembers("")); index.put("com.codename1.ai.vision.VisionBackend", splitMembers("")); index.put("com.codename1.ai.vision.VisionBackends", splitMembers("")); + index.put("com.codename1.ai.vision.VisionCameraView", splitMembers("")); index.put("com.codename1.ai.vision.VisionException", splitMembers("")); index.put("com.codename1.ai.vision.VisionFeature", splitMembers("")); index.put("com.codename1.ai.vision.VisionImage", splitMembers("")); @@ -4165,16 +4395,17 @@ private static void fillFieldIndex1(Map index) { index.put("com.codename1.analytics.ConsentMode", splitMembers("")); index.put("com.codename1.analytics.FirebaseAnalyticsProvider", splitMembers("")); index.put("com.codename1.analytics.FirebaseAnalyticsProvider.Bridge", splitMembers("")); + } + + private static void fillFieldIndex2(Map index) { index.put("com.codename1.analytics.GoogleAnalyticsProvider", splitMembers("")); index.put("com.codename1.analytics.LegacyAnalyticsProviderAdapter", splitMembers("")); index.put("com.codename1.analytics.LoggingAnalyticsProvider", splitMembers("")); index.put("com.codename1.analytics.MatomoAnalyticsProvider", splitMembers("")); + index.put("com.codename1.annotations.AppIntent", splitMembers("")); index.put("com.codename1.annotations.Async", splitMembers("")); index.put("com.codename1.annotations.Async.Execute", splitMembers("")); index.put("com.codename1.annotations.Async.Schedule", splitMembers("")); - } - - private static void fillFieldIndex2(Map index) { index.put("com.codename1.annotations.Bind", splitMembers("")); index.put("com.codename1.annotations.Bindable", splitMembers("")); index.put("com.codename1.annotations.Column", splitMembers("")); @@ -4184,9 +4415,17 @@ private static void fillFieldIndex2(Map index) { index.put("com.codename1.annotations.DisableNullChecksAndArrayBoundsChecks", splitMembers("")); index.put("com.codename1.annotations.Email", splitMembers("")); index.put("com.codename1.annotations.Entity", splitMembers("")); + index.put("com.codename1.annotations.EntityId", splitMembers("")); + index.put("com.codename1.annotations.EntityImage", splitMembers("")); + index.put("com.codename1.annotations.EntityQuery", splitMembers("")); + index.put("com.codename1.annotations.EntityQuery.Kind", splitMembers("")); + index.put("com.codename1.annotations.EntitySubtitle", splitMembers("")); + index.put("com.codename1.annotations.EntityTitle", splitMembers("")); index.put("com.codename1.annotations.ExistIn", splitMembers("")); index.put("com.codename1.annotations.Fused", splitMembers("")); index.put("com.codename1.annotations.Id", splitMembers("")); + index.put("com.codename1.annotations.IntentEntity", splitMembers("")); + index.put("com.codename1.annotations.IntentParam", splitMembers("")); index.put("com.codename1.annotations.JsonIgnore", splitMembers("")); index.put("com.codename1.annotations.JsonProperty", splitMembers("")); index.put("com.codename1.annotations.Length", splitMembers("")); @@ -4203,9 +4442,29 @@ private static void fillFieldIndex2(Map index) { index.put("com.codename1.annotations.XmlElement", splitMembers("")); index.put("com.codename1.annotations.XmlRoot", splitMembers("")); index.put("com.codename1.annotations.XmlTransient", splitMembers("")); + index.put("com.codename1.annotations.buildhints.Android", splitMembers("")); + index.put("com.codename1.annotations.buildhints.AndroidThemeMode", splitMembers("")); + index.put("com.codename1.annotations.buildhints.Build", splitMembers("")); + index.put("com.codename1.annotations.buildhints.Desktop", splitMembers("")); + index.put("com.codename1.annotations.buildhints.DesktopTitleBar", splitMembers("")); + index.put("com.codename1.annotations.buildhints.HardenControlFlow", splitMembers("")); + index.put("com.codename1.annotations.buildhints.HardenLevel", splitMembers("")); + index.put("com.codename1.annotations.buildhints.HardenStrings", splitMembers("")); + index.put("com.codename1.annotations.buildhints.Hardening", splitMembers("")); + index.put("com.codename1.annotations.buildhints.InstallLocation", splitMembers("")); + index.put("com.codename1.annotations.buildhints.Ios", splitMembers("")); + index.put("com.codename1.annotations.buildhints.IosDependencyManager", splitMembers("")); + index.put("com.codename1.annotations.buildhints.IosPrivacy", splitMembers("")); + index.put("com.codename1.annotations.buildhints.IosProjectType", splitMembers("")); + index.put("com.codename1.annotations.buildhints.IosThemeMode", splitMembers("")); + index.put("com.codename1.annotations.buildhints.NativeThemeMode", splitMembers("")); + index.put("com.codename1.annotations.buildhints.OnDeviceDebug", splitMembers("")); index.put("com.codename1.annotations.graphql.GraphQLClient", splitMembers("")); index.put("com.codename1.annotations.graphql.Mutation", splitMembers("")); index.put("com.codename1.annotations.graphql.Query", splitMembers("")); + } + + private static void fillFieldIndex3(Map index) { index.put("com.codename1.annotations.graphql.Subscription", splitMembers("")); index.put("com.codename1.annotations.graphql.Var", splitMembers("")); index.put("com.codename1.annotations.grpc.GrpcClient", splitMembers("")); @@ -4239,9 +4498,6 @@ private static void fillFieldIndex2(Map index) { index.put("com.codename1.ar.ARHitResult.Type", splitMembers("")); index.put("com.codename1.ar.ARImageAnchor", splitMembers("")); index.put("com.codename1.ar.ARLightEstimate", splitMembers("")); - } - - private static void fillFieldIndex3(Map index) { index.put("com.codename1.ar.ARModel", splitMembers("")); index.put("com.codename1.ar.ARNode", splitMembers("")); index.put("com.codename1.ar.ARPlane", splitMembers("")); @@ -4273,6 +4529,9 @@ private static void fillFieldIndex3(Map index) { index.put("com.codename1.binding.Binding", splitMembers("")); index.put("com.codename1.binding.NotifiableBinding", splitMembers("")); index.put("com.codename1.bluetooth.AdapterState", splitMembers("")); + } + + private static void fillFieldIndex4(Map index) { index.put("com.codename1.bluetooth.AdapterStateListener", splitMembers("")); index.put("com.codename1.bluetooth.Bluetooth", splitMembers("")); index.put("com.codename1.bluetooth.BluetoothDevice", splitMembers("")); @@ -4306,9 +4565,6 @@ private static void fillFieldIndex3(Map index) { index.put("com.codename1.bluetooth.le.L2capServer", splitMembers("")); index.put("com.codename1.bluetooth.le.ScanFilter", splitMembers("")); index.put("com.codename1.bluetooth.le.ScanListener", splitMembers("")); - } - - private static void fillFieldIndex4(Map index) { index.put("com.codename1.bluetooth.le.ScanMode", splitMembers("")); index.put("com.codename1.bluetooth.le.ScanResult", splitMembers("")); index.put("com.codename1.bluetooth.le.ScanSettings", splitMembers("")); @@ -4340,6 +4596,9 @@ private static void fillFieldIndex4(Map index) { index.put("com.codename1.calendar.CalendarCache", splitMembers("")); index.put("com.codename1.calendar.CalendarCapabilities", splitMembers("")); index.put("com.codename1.calendar.CalendarCapability", splitMembers("")); + } + + private static void fillFieldIndex5(Map index) { index.put("com.codename1.calendar.CalendarChange", splitMembers("")); index.put("com.codename1.calendar.CalendarChange.ChangeType", splitMembers("")); index.put("com.codename1.calendar.CalendarChange.EntityType", splitMembers("")); @@ -4373,9 +4632,6 @@ private static void fillFieldIndex4(Map index) { index.put("com.codename1.calendar.CalendarTokenProvider", splitMembers("")); index.put("com.codename1.calendar.DefaultCalendarHttpTransport", splitMembers("")); index.put("com.codename1.calendar.FreeBusyInterval", splitMembers("")); - } - - private static void fillFieldIndex5(Map index) { index.put("com.codename1.calendar.GoogleCalendarSource", splitMembers("")); index.put("com.codename1.calendar.ICalendarCodec", splitMembers("")); index.put("com.codename1.calendar.LocalCalendarSource", splitMembers("")); @@ -4407,6 +4663,9 @@ private static void fillFieldIndex5(Map index) { index.put("com.codename1.car.CarActionListener", splitMembers("")); index.put("com.codename1.car.CarActionStrip", splitMembers("")); index.put("com.codename1.car.CarApplication", splitMembers("")); + } + + private static void fillFieldIndex6(Map index) { index.put("com.codename1.car.CarColor", splitMembers("")); index.put("com.codename1.car.CarConnectionListener", splitMembers("")); index.put("com.codename1.car.CarContext", splitMembers("")); @@ -4440,9 +4699,6 @@ private static void fillFieldIndex5(Map index) { index.put("com.codename1.charts.models.Point", splitMembers("")); index.put("com.codename1.charts.models.RangeCategorySeries", splitMembers("")); index.put("com.codename1.charts.models.SeriesSelection", splitMembers("")); - } - - private static void fillFieldIndex6(Map index) { index.put("com.codename1.charts.models.TimeSeries", splitMembers("")); index.put("com.codename1.charts.models.XYMultipleSeriesDataset", splitMembers("")); index.put("com.codename1.charts.models.XYSeries", splitMembers("")); @@ -4474,6 +4730,9 @@ private static void fillFieldIndex6(Map index) { index.put("com.codename1.charts.views.CubicLineChart", splitMembers("")); index.put("com.codename1.charts.views.DialChart", splitMembers("")); index.put("com.codename1.charts.views.DoughnutChart", splitMembers("")); + } + + private static void fillFieldIndex7(Map index) { index.put("com.codename1.charts.views.LineChart", splitMembers("")); index.put("com.codename1.charts.views.PieChart", splitMembers("")); index.put("com.codename1.charts.views.PieMapper", splitMembers("")); @@ -4507,9 +4766,6 @@ private static void fillFieldIndex6(Map index) { index.put("com.codename1.components.FileTreeModel", splitMembers("")); index.put("com.codename1.components.FloatingActionButton", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSTATE_DEFAULTSTATE_PRESSEDSTATE_ROLLOVERSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); index.put("com.codename1.components.FloatingHint", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); - } - - private static void fillFieldIndex7(Map index) { index.put("com.codename1.components.ImageViewer", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORIMAGE_FILLIMAGE_FITLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); index.put("com.codename1.components.InfiniteProgress", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); index.put("com.codename1.components.InfiniteScrollAdapter", splitMembers("")); @@ -4541,13 +4797,19 @@ private static void fillFieldIndex7(Map index) { index.put("com.codename1.components.ToastBar", splitMembers("")); index.put("com.codename1.components.WebBrowser", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); index.put("com.codename1.contacts.Address", splitMembers("")); + } + + private static void fillFieldIndex8(Map index) { index.put("com.codename1.contacts.Contact", splitMembers("")); index.put("com.codename1.contacts.ContactsManager", splitMembers("")); index.put("com.codename1.contacts.ContactsModel", splitMembers("")); index.put("com.codename1.crash.CrashProtection", splitMembers("")); index.put("com.codename1.crash.PiiScrubber", splitMembers("")); index.put("com.codename1.db.Cursor", splitMembers("")); + index.put("com.codename1.db.CursorExt", splitMembers("")); index.put("com.codename1.db.Database", splitMembers("")); + index.put("com.codename1.db.DatabaseConfig", splitMembers("")); + index.put("com.codename1.db.DatabaseEncryptionException", splitMembers("")); index.put("com.codename1.db.Row", splitMembers("")); index.put("com.codename1.db.RowExt", splitMembers("")); index.put("com.codename1.db.ThreadSafeDatabase", splitMembers("")); @@ -4574,9 +4836,6 @@ private static void fillFieldIndex7(Map index) { index.put("com.codename1.gaming.VirtualButton", splitMembers("")); index.put("com.codename1.gaming.VirtualJoystick", splitMembers("")); index.put("com.codename1.gaming.VoiceListener", splitMembers("")); - } - - private static void fillFieldIndex8(Map index) { index.put("com.codename1.gaming.level.AssetCatalog", splitMembers("")); index.put("com.codename1.gaming.level.AssetDef", splitMembers("")); index.put("com.codename1.gaming.level.AssetDef.Kind", splitMembers("")); @@ -4605,6 +4864,9 @@ private static void fillFieldIndex8(Map index) { index.put("com.codename1.gaming.level.TileLayer", splitMembers("")); index.put("com.codename1.gaming.physics.BodyType", splitMembers("")); index.put("com.codename1.gaming.physics.ContactListener", splitMembers("")); + } + + private static void fillFieldIndex9(Map index) { index.put("com.codename1.gaming.physics.PhysicsBody", splitMembers("")); index.put("com.codename1.gaming.physics.PhysicsContact", splitMembers("")); index.put("com.codename1.gaming.physics.PhysicsJoint", splitMembers("")); @@ -4641,9 +4903,6 @@ private static void fillFieldIndex8(Map index) { index.put("com.codename1.gaming.physics.box2d.collision.TimeOfImpact.TOIOutput", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.collision.TimeOfImpact.TOIOutputState", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.collision.WorldManifold", splitMembers("")); - } - - private static void fillFieldIndex9(Map index) { index.put("com.codename1.gaming.physics.box2d.collision.broadphase.BroadPhase", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.collision.broadphase.BroadPhaseStrategy", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.collision.broadphase.DynamicTree", splitMembers("")); @@ -4672,6 +4931,9 @@ private static void fillFieldIndex9(Map index) { index.put("com.codename1.gaming.physics.box2d.common.Vec3", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.Body", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.BodyDef", splitMembers("")); + } + + private static void fillFieldIndex10(Map index) { index.put("com.codename1.gaming.physics.box2d.dynamics.BodyType", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.ContactManager", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.Filter", splitMembers("")); @@ -4708,9 +4970,6 @@ private static void fillFieldIndex9(Map index) { index.put("com.codename1.gaming.physics.box2d.dynamics.joints.FrictionJoint", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.joints.FrictionJointDef", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.joints.GearJoint", splitMembers("")); - } - - private static void fillFieldIndex10(Map index) { index.put("com.codename1.gaming.physics.box2d.dynamics.joints.GearJointDef", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.joints.Jacobian", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.dynamics.joints.Joint", splitMembers("")); @@ -4739,6 +4998,9 @@ private static void fillFieldIndex10(Map index) { index.put("com.codename1.gaming.physics.box2d.pooling.arrays.IntArray", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.pooling.arrays.Vec2Array", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.pooling.normal.CircleStack", splitMembers("")); + } + + private static void fillFieldIndex11(Map index) { index.put("com.codename1.gaming.physics.box2d.pooling.normal.DefaultWorldPool", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.pooling.normal.MutableStack", splitMembers("")); index.put("com.codename1.gaming.physics.box2d.pooling.normal.OrderedStack", splitMembers("")); @@ -4775,9 +5037,6 @@ private static void fillFieldIndex10(Map index) { index.put("com.codename1.health.AggregateResult", splitMembers("")); index.put("com.codename1.health.BloodPressureSample", splitMembers("")); index.put("com.codename1.health.CategorySample", splitMembers("")); - } - - private static void fillFieldIndex11(Map index) { index.put("com.codename1.health.Health", splitMembers("")); index.put("com.codename1.health.HealthAccess", splitMembers("")); index.put("com.codename1.health.HealthAggregationStyle", splitMembers("")); @@ -4806,6 +5065,9 @@ private static void fillFieldIndex11(Map index) { index.put("com.codename1.health.HealthUnitDimension", splitMembers("")); index.put("com.codename1.health.HealthWriteResult", splitMembers("")); index.put("com.codename1.health.QuantitySample", splitMembers("")); + } + + private static void fillFieldIndex12(Map index) { index.put("com.codename1.health.RecordingMethod", splitMembers("")); index.put("com.codename1.health.SamplePage", splitMembers("")); index.put("com.codename1.health.SampleQuery", splitMembers("")); @@ -4842,9 +5104,6 @@ private static void fillFieldIndex11(Map index) { index.put("com.codename1.health.sensors.TemperatureMeasurement", splitMembers("")); index.put("com.codename1.health.sensors.WeightMeasurement", splitMembers("")); index.put("com.codename1.health.workout.WorkoutConfiguration", splitMembers("")); - } - - private static void fillFieldIndex12(Map index) { index.put("com.codename1.health.workout.WorkoutEvent", splitMembers("")); index.put("com.codename1.health.workout.WorkoutEvent.Kind", splitMembers("")); index.put("com.codename1.health.workout.WorkoutLocationType", splitMembers("")); @@ -4852,6 +5111,73 @@ private static void fillFieldIndex12(Map index) { index.put("com.codename1.health.workout.WorkoutSession", splitMembers("")); index.put("com.codename1.health.workout.WorkoutSessionListener", splitMembers("")); index.put("com.codename1.health.workout.WorkoutSessionState", splitMembers("")); + index.put("com.codename1.home.Accessory", splitMembers("")); + index.put("com.codename1.home.AccessoryCategory", splitMembers("")); + index.put("com.codename1.home.AccessoryService", splitMembers("")); + index.put("com.codename1.home.AirQualityLevel", splitMembers("")); + index.put("com.codename1.home.AlarmState", splitMembers("")); + index.put("com.codename1.home.ChargingState", splitMembers("")); + index.put("com.codename1.home.DoorState", splitMembers("")); + index.put("com.codename1.home.FanMode", splitMembers("")); + index.put("com.codename1.home.HeatingCoolingMode", splitMembers("")); + index.put("com.codename1.home.HomeAuthorizationStatus", splitMembers("")); + index.put("com.codename1.home.HomeAvailability", splitMembers("")); + index.put("com.codename1.home.HomeBackend", splitMembers("")); + index.put("com.codename1.home.HomeChangeListener", splitMembers("")); + index.put("com.codename1.home.HomeConfigurationException", splitMembers("")); + index.put("com.codename1.home.HomeError", splitMembers("")); + index.put("com.codename1.home.HomeException", splitMembers("")); + index.put("com.codename1.home.HomeRoom", splitMembers("")); + index.put("com.codename1.home.HomeStructure", splitMembers("")); + index.put("com.codename1.home.HomeStructureEvent", splitMembers("")); + index.put("com.codename1.home.HomeStructureListener", splitMembers("")); + index.put("com.codename1.home.HomeZone", splitMembers("")); + } + + private static void fillFieldIndex13(Map index) { + index.put("com.codename1.home.LockState", splitMembers("")); + index.put("com.codename1.home.PositionState", splitMembers("")); + index.put("com.codename1.home.Scene", splitMembers("")); + index.put("com.codename1.home.SceneAction", splitMembers("")); + index.put("com.codename1.home.SceneType", splitMembers("")); + index.put("com.codename1.home.ServiceType", splitMembers("")); + index.put("com.codename1.home.SmartHome", splitMembers("")); + index.put("com.codename1.home.StructureChangeKind", splitMembers("")); + index.put("com.codename1.home.SubscriptionRequest", splitMembers("")); + index.put("com.codename1.home.Trait", splitMembers("")); + index.put("com.codename1.home.TraitChangeBatch", splitMembers("")); + index.put("com.codename1.home.TraitConstraint", splitMembers("")); + index.put("com.codename1.home.TraitReadRequest", splitMembers("")); + index.put("com.codename1.home.TraitReading", splitMembers("")); + index.put("com.codename1.home.TraitSubscription", splitMembers("")); + index.put("com.codename1.home.TraitUnit", splitMembers("")); + index.put("com.codename1.home.TraitUnitDimension", splitMembers("")); + index.put("com.codename1.home.TraitValue", splitMembers("")); + index.put("com.codename1.home.TraitValueKind", splitMembers("")); + index.put("com.codename1.home.TraitWrite", splitMembers("")); + index.put("com.codename1.home.TraitWriteResult", splitMembers("")); + index.put("com.codename1.home.commissioning.Commissioner", splitMembers("")); + index.put("com.codename1.home.commissioning.CommissioningRequest", splitMembers("")); + index.put("com.codename1.home.commissioning.CommissioningResult", splitMembers("")); + index.put("com.codename1.home.commissioning.CommissioningStyle", splitMembers("")); + index.put("com.codename1.home.commissioning.SetupPayload", splitMembers("")); + index.put("com.codename1.home.spi.HomeBridge", splitMembers("")); + index.put("com.codename1.intents.AppEntity", splitMembers("")); + index.put("com.codename1.intents.DynamicIntent", splitMembers("")); + index.put("com.codename1.intents.EntitySelectionHandler", splitMembers("")); + index.put("com.codename1.intents.Exposure", splitMembers("")); + index.put("com.codename1.intents.IntentCompletion", splitMembers("")); + index.put("com.codename1.intents.IntentContext", splitMembers("")); + index.put("com.codename1.intents.IntentDates", splitMembers("")); + index.put("com.codename1.intents.IntentDeclaration", splitMembers("")); + index.put("com.codename1.intents.IntentDispatcher", splitMembers("")); + index.put("com.codename1.intents.IntentParameterInfo", splitMembers("")); + index.put("com.codename1.intents.IntentParameterType", splitMembers("")); + index.put("com.codename1.intents.IntentResult", splitMembers("")); + index.put("com.codename1.intents.IntentSerializer", splitMembers("")); + index.put("com.codename1.intents.IntentSource", splitMembers("")); + index.put("com.codename1.intents.Intents", splitMembers("")); + index.put("com.codename1.intents.spi.IntentBridge", splitMembers("")); index.put("com.codename1.io.AccessToken", splitMembers("")); index.put("com.codename1.io.BufferedInputStream", splitMembers("")); index.put("com.codename1.io.BufferedOutputStream", splitMembers("")); @@ -4873,6 +5199,9 @@ private static void fillFieldIndex12(Map index) { index.put("com.codename1.io.JSONParser", splitMembers("")); index.put("com.codename1.io.JSONParser.RawJson", splitMembers("")); index.put("com.codename1.io.JSONWriter", splitMembers("")); + } + + private static void fillFieldIndex14(Map index) { index.put("com.codename1.io.JSONWriter.ArrayBuilder", splitMembers("")); index.put("com.codename1.io.JSONWriter.ObjectBuilder", splitMembers("")); index.put("com.codename1.io.Log", splitMembers("")); @@ -4909,9 +5238,6 @@ private static void fillFieldIndex12(Map index) { index.put("com.codename1.io.bonjour.BonjourService", splitMembers("")); index.put("com.codename1.io.bonjour.BonjourServiceListener", splitMembers("")); index.put("com.codename1.io.graphql.GraphQL", splitMembers("")); - } - - private static void fillFieldIndex13(Map index) { index.put("com.codename1.io.graphql.GraphQLClients", splitMembers("")); index.put("com.codename1.io.graphql.GraphQLClients.Factory", splitMembers("")); index.put("com.codename1.io.graphql.GraphQLError", splitMembers("")); @@ -4940,6 +5266,9 @@ private static void fillFieldIndex13(Map index) { index.put("com.codename1.io.gzip.GZIPHeader", splitMembers("")); index.put("com.codename1.io.gzip.GZIPInputStream", splitMembers("")); index.put("com.codename1.io.gzip.GZIPOutputStream", splitMembers("")); + } + + private static void fillFieldIndex15(Map index) { index.put("com.codename1.io.gzip.Inflater", splitMembers("")); index.put("com.codename1.io.gzip.InflaterInputStream", splitMembers("")); index.put("com.codename1.io.gzip.JZlib", splitMembers("")); @@ -4976,9 +5305,6 @@ private static void fillFieldIndex13(Map index) { index.put("com.codename1.io.usb.UsbDeviceListener", splitMembers("")); index.put("com.codename1.io.usb.UsbPlatform", splitMembers("")); index.put("com.codename1.io.webauthn.PublicKeyCredential", splitMembers("")); - } - - private static void fillFieldIndex14(Map index) { index.put("com.codename1.io.webauthn.PublicKeyCredentialCreationOptions", splitMembers("")); index.put("com.codename1.io.webauthn.PublicKeyCredentialCreationOptions.Builder", splitMembers("")); index.put("com.codename1.io.webauthn.PublicKeyCredentialRequestOptions", splitMembers("")); @@ -5007,6 +5333,9 @@ private static void fillFieldIndex14(Map index) { index.put("com.codename1.l10n.ParseException", splitMembers("")); index.put("com.codename1.l10n.SimpleDateFormat", splitMembers("")); index.put("com.codename1.location.Geofence", splitMembers("")); + } + + private static void fillFieldIndex16(Map index) { index.put("com.codename1.location.GeofenceListener", splitMembers("")); index.put("com.codename1.location.GeofenceManager", splitMembers("")); index.put("com.codename1.location.GeofenceManager.Listener", splitMembers("")); @@ -5043,9 +5372,6 @@ private static void fillFieldIndex14(Map index) { index.put("com.codename1.maps.layers.AbstractLayer", splitMembers("")); index.put("com.codename1.maps.layers.ArrowLinesLayer", splitMembers("")); index.put("com.codename1.maps.layers.Layer", splitMembers("")); - } - - private static void fillFieldIndex15(Map index) { index.put("com.codename1.maps.layers.LinesLayer", splitMembers("")); index.put("com.codename1.maps.layers.PointLayer", splitMembers("")); index.put("com.codename1.maps.layers.PointsLayer", splitMembers("")); @@ -5074,6 +5400,9 @@ private static void fillFieldIndex15(Map index) { index.put("com.codename1.maps.vector.StyleLayer", splitMembers("")); index.put("com.codename1.maps.vector.TileCallback", splitMembers("")); index.put("com.codename1.maps.vector.TileSource", splitMembers("")); + } + + private static void fillFieldIndex17(Map index) { index.put("com.codename1.maps.vector.VectorFeature", splitMembers("")); index.put("com.codename1.maps.vector.VectorLayer", splitMembers("")); index.put("com.codename1.maps.vector.VectorMapEngine", splitMembers("")); @@ -5110,9 +5439,6 @@ private static void fillFieldIndex15(Map index) { index.put("com.codename1.media.SpeechRecognizer", splitMembers("")); index.put("com.codename1.media.TextToSpeech", splitMembers("")); index.put("com.codename1.media.TimedRecognitionCallback", splitMembers("")); - } - - private static void fillFieldIndex16(Map index) { index.put("com.codename1.media.Transcriber", splitMembers("")); index.put("com.codename1.media.TranscriptionRequest", splitMembers("")); index.put("com.codename1.media.TranscriptionResult", splitMembers("")); @@ -5141,6 +5467,9 @@ private static void fillFieldIndex16(Map index) { index.put("com.codename1.nfc.NfcError", splitMembers("")); index.put("com.codename1.nfc.NfcException", splitMembers("")); index.put("com.codename1.nfc.NfcF", splitMembers("")); + } + + private static void fillFieldIndex18(Map index) { index.put("com.codename1.nfc.NfcListener", splitMembers("")); index.put("com.codename1.nfc.NfcReadOptions", splitMembers("")); index.put("com.codename1.nfc.NfcV", splitMembers("")); @@ -5177,9 +5506,6 @@ private static void fillFieldIndex16(Map index) { index.put("com.codename1.plugin.event.OpenGalleryEvent", splitMembers("")); index.put("com.codename1.plugin.event.PluginEvent", splitMembers("")); index.put("com.codename1.printing.PrintResult", splitMembers("")); - } - - private static void fillFieldIndex17(Map index) { index.put("com.codename1.printing.PrintResultListener", splitMembers("")); index.put("com.codename1.printing.Printer", splitMembers("")); index.put("com.codename1.processing.Result", splitMembers("")); @@ -5208,6 +5534,9 @@ private static void fillFieldIndex17(Map index) { index.put("com.codename1.properties.UiBinding", splitMembers("")); index.put("com.codename1.properties.UiBinding.BooleanConverter", splitMembers("")); index.put("com.codename1.properties.UiBinding.BoundTableModel", splitMembers("")); + } + + private static void fillFieldIndex19(Map index) { index.put("com.codename1.properties.UiBinding.CheckBoxRadioSelectionAdapter", splitMembers("")); index.put("com.codename1.properties.UiBinding.ComponentAdapter", splitMembers("")); index.put("com.codename1.properties.UiBinding.DateConverter", splitMembers("")); @@ -5244,9 +5573,6 @@ private static void fillFieldIndex17(Map index) { index.put("com.codename1.router.PopGuard", splitMembers("")); index.put("com.codename1.router.PopReason", splitMembers("")); index.put("com.codename1.router.RouteDispatcher", splitMembers("")); - } - - private static void fillFieldIndex18(Map index) { index.put("com.codename1.security.AuthenticationOptions", splitMembers("")); index.put("com.codename1.security.Base32", splitMembers("")); index.put("com.codename1.security.BiometricError", splitMembers("")); @@ -5270,9 +5596,14 @@ private static void fillFieldIndex18(Map index) { index.put("com.codename1.security.SecureRandom", splitMembers("")); index.put("com.codename1.security.SecureStorage", splitMembers("")); index.put("com.codename1.security.Signature", splitMembers("")); + index.put("com.codename1.security.TapjackingPolicy", splitMembers("")); + index.put("com.codename1.security.hardening.Hardening", splitMembers("")); index.put("com.codename1.security.shield.AppShield", splitMembers("")); index.put("com.codename1.security.shield.FailureMode", splitMembers("")); index.put("com.codename1.security.shield.HostPolicy", splitMembers("")); + } + + private static void fillFieldIndex20(Map index) { index.put("com.codename1.security.shield.PinSet", splitMembers("")); index.put("com.codename1.security.shield.ShieldConfig", splitMembers("")); index.put("com.codename1.security.shield.ShieldException", splitMembers("")); @@ -5311,9 +5642,6 @@ private static void fillFieldIndex18(Map index) { index.put("com.codename1.social.Login", splitMembers("")); index.put("com.codename1.social.LoginCallback", splitMembers("")); index.put("com.codename1.social.MicrosoftConnect", splitMembers("")); - } - - private static void fillFieldIndex19(Map index) { index.put("com.codename1.surfaces.LiveActivity", splitMembers("")); index.put("com.codename1.surfaces.LiveActivityDescriptor", splitMembers("")); index.put("com.codename1.surfaces.SurfaceActionEvent", splitMembers("")); @@ -5340,6 +5668,9 @@ private static void fillFieldIndex19(Map index) { index.put("com.codename1.surfaces.WidgetKind", splitMembers("")); index.put("com.codename1.surfaces.WidgetSize", splitMembers("")); index.put("com.codename1.surfaces.WidgetTimeline", splitMembers("")); + } + + private static void fillFieldIndex21(Map index) { index.put("com.codename1.surfaces.WidgetTimeline.Entry", splitMembers("")); index.put("com.codename1.surfaces.spi.SurfaceBridge", splitMembers("")); index.put("com.codename1.system.CrashReport", splitMembers("")); @@ -5378,9 +5709,6 @@ private static void fillFieldIndex19(Map index) { index.put("com.codename1.ui.CheckBox", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSTATE_DEFAULTSTATE_PRESSEDSTATE_ROLLOVERSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); index.put("com.codename1.ui.ClipboardContent", splitMembers("MIME_ASCIIDOCMIME_FILEMIME_GIFMIME_HTMLMIME_JPEGMIME_MARKDOWNMIME_PNGMIME_RTFMIME_TEXT")); index.put("com.codename1.ui.CodeCompletion", splitMembers("")); - } - - private static void fillFieldIndex20(Map index) { index.put("com.codename1.ui.CodeCompletionProvider", splitMembers("")); index.put("com.codename1.ui.CodeDiagnostic", splitMembers("ERRORINFOWARNING")); index.put("com.codename1.ui.CodeEditor", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); @@ -5407,6 +5735,9 @@ private static void fillFieldIndex20(Map index) { index.put("com.codename1.ui.EditField", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORKEY_BACKSPACEKEY_COPYKEY_CUTKEY_DELETEKEY_DOWNKEY_ENDKEY_ESCAPEKEY_HOMEKEY_LEFTKEY_PAGE_DOWNKEY_PAGE_UPKEY_PASTEKEY_REDOKEY_RIGHTKEY_SELECT_ALLKEY_TABKEY_UNDOKEY_UPLEFTMOD_ALTMOD_CTRLMOD_SHIFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); index.put("com.codename1.ui.Editable", splitMembers("")); index.put("com.codename1.ui.EncodedImage", splitMembers("")); + } + + private static void fillFieldIndex22(Map index) { index.put("com.codename1.ui.Font", splitMembers("BASELINEBOTTOMCENTERCENTER_BEHAVIOR_CENTERCENTER_BEHAVIOR_CENTER_ABSOLUTECENTER_BEHAVIOR_SCALECENTER_BEHAVIOR_TOTAL_BELOWDENSITY_2HDDENSITY_4KDENSITY_560DENSITY_HDDENSITY_HIGHDENSITY_LOWDENSITY_MEDIUMDENSITY_VERY_HIGHDENSITY_VERY_LOWEASTFACE_MONOSPACEFACE_PROPORTIONALFACE_SYSTEMGALLERY_ALLGALLERY_ALL_MULTIGALLERY_IMAGEGALLERY_IMAGE_MULTIGALLERY_VIDEOGALLERY_VIDEO_MULTILEFTNATIVE_ITALIC_BLACKNATIVE_ITALIC_BOLDNATIVE_ITALIC_LIGHTNATIVE_ITALIC_REGULARNATIVE_ITALIC_THINNATIVE_MAIN_BLACKNATIVE_MAIN_BOLDNATIVE_MAIN_LIGHTNATIVE_MAIN_REGULARNATIVE_MAIN_THINNORTHPICKER_TYPE_CALENDARPICKER_TYPE_DATEPICKER_TYPE_DATE_AND_TIMEPICKER_TYPE_DURATIONPICKER_TYPE_DURATION_HOURSPICKER_TYPE_DURATION_MINUTESPICKER_TYPE_STRINGSPICKER_TYPE_TIMERIGHTSIZE_LARGESIZE_MEDIUMSIZE_SMALLSMS_BOTHSMS_INTERACTIVESMS_NOT_SUPPORTEDSMS_SEAMLESSSOUTHSTYLE_BOLDSTYLE_ITALICSTYLE_PLAINSTYLE_UNDERLINEDTOPWEST")); index.put("com.codename1.ui.FontImage", splitMembers("MATERIAL_10KMATERIAL_10MPMATERIAL_11MPMATERIAL_123MATERIAL_12MPMATERIAL_13MPMATERIAL_14MPMATERIAL_15MPMATERIAL_16MPMATERIAL_17MPMATERIAL_18MPMATERIAL_18_UP_RATINGMATERIAL_19MPMATERIAL_1KMATERIAL_1K_PLUSMATERIAL_1X_MOBILEDATAMATERIAL_20MPMATERIAL_21MPMATERIAL_22MPMATERIAL_23MPMATERIAL_24MPMATERIAL_2KMATERIAL_2K_PLUSMATERIAL_2MPMATERIAL_30FPSMATERIAL_30FPS_SELECTMATERIAL_360MATERIAL_3D_ROTATIONMATERIAL_3G_MOBILEDATAMATERIAL_3KMATERIAL_3K_PLUSMATERIAL_3MPMATERIAL_3PMATERIAL_4G_MOBILEDATAMATERIAL_4G_PLUS_MOBILEDATAMATERIAL_4KMATERIAL_4K_PLUSMATERIAL_4MPMATERIAL_5GMATERIAL_5KMATERIAL_5K_PLUSMATERIAL_5MPMATERIAL_60FPSMATERIAL_60FPS_SELECTMATERIAL_6KMATERIAL_6K_PLUSMATERIAL_6MPMATERIAL_6_FT_APARTMATERIAL_7KMATERIAL_7K_PLUSMATERIAL_7MPMATERIAL_8KMATERIAL_8K_PLUSMATERIAL_8MPMATERIAL_9KMATERIAL_9K_PLUSMATERIAL_9MPMATERIAL_ABCMATERIAL_ACCESSIBILITYMATERIAL_ACCESSIBILITY_NEWMATERIAL_ACCESSIBLEMATERIAL_ACCESSIBLE_FORWARDMATERIAL_ACCESS_ALARMMATERIAL_ACCESS_ALARMSMATERIAL_ACCESS_TIMEMATERIAL_ACCESS_TIME_FILLEDMATERIAL_ACCOUNT_BALANCEMATERIAL_ACCOUNT_BALANCE_WALLETMATERIAL_ACCOUNT_BOXMATERIAL_ACCOUNT_CIRCLEMATERIAL_ACCOUNT_TREEMATERIAL_AC_UNITMATERIAL_ADBMATERIAL_ADDMATERIAL_ADDCHARTMATERIAL_ADD_ALARMMATERIAL_ADD_ALERTMATERIAL_ADD_A_PHOTOMATERIAL_ADD_BOXMATERIAL_ADD_BUSINESSMATERIAL_ADD_CALLMATERIAL_ADD_CARDMATERIAL_ADD_CHARTMATERIAL_ADD_CIRCLEMATERIAL_ADD_CIRCLE_OUTLINEMATERIAL_ADD_COMMENTMATERIAL_ADD_HOMEMATERIAL_ADD_HOME_WORKMATERIAL_ADD_IC_CALLMATERIAL_ADD_LINKMATERIAL_ADD_LOCATIONMATERIAL_ADD_LOCATION_ALTMATERIAL_ADD_MODERATORMATERIAL_ADD_PHOTO_ALTERNATEMATERIAL_ADD_REACTIONMATERIAL_ADD_ROADMATERIAL_ADD_SHOPPING_CARTMATERIAL_ADD_TASKMATERIAL_ADD_TO_DRIVEMATERIAL_ADD_TO_HOME_SCREENMATERIAL_ADD_TO_PHOTOSMATERIAL_ADD_TO_QUEUEMATERIAL_ADF_SCANNERMATERIAL_ADJUSTMATERIAL_ADMIN_PANEL_SETTINGSMATERIAL_ADOBEMATERIAL_ADS_CLICKMATERIAL_AD_UNITSMATERIAL_AGRICULTUREMATERIAL_AIRMATERIAL_AIRLINESMATERIAL_AIRLINE_SEAT_FLATMATERIAL_AIRLINE_SEAT_FLAT_ANGLEDMATERIAL_AIRLINE_SEAT_INDIVIDUAL_SUITEMATERIAL_AIRLINE_SEAT_LEGROOM_EXTRAMATERIAL_AIRLINE_SEAT_LEGROOM_NORMALMATERIAL_AIRLINE_SEAT_LEGROOM_REDUCEDMATERIAL_AIRLINE_SEAT_RECLINE_EXTRAMATERIAL_AIRLINE_SEAT_RECLINE_NORMALMATERIAL_AIRLINE_STOPSMATERIAL_AIRPLANEMODE_ACTIVEMATERIAL_AIRPLANEMODE_INACTIVEMATERIAL_AIRPLANEMODE_OFFMATERIAL_AIRPLANEMODE_ONMATERIAL_AIRPLANE_TICKETMATERIAL_AIRPLAYMATERIAL_AIRPORT_SHUTTLEMATERIAL_ALARMMATERIAL_ALARM_ADDMATERIAL_ALARM_OFFMATERIAL_ALARM_ONMATERIAL_ALBUMMATERIAL_ALIGN_HORIZONTAL_CENTERMATERIAL_ALIGN_HORIZONTAL_LEFTMATERIAL_ALIGN_HORIZONTAL_RIGHTMATERIAL_ALIGN_VERTICAL_BOTTOMMATERIAL_ALIGN_VERTICAL_CENTERMATERIAL_ALIGN_VERTICAL_TOPMATERIAL_ALL_INBOXMATERIAL_ALL_INCLUSIVEMATERIAL_ALL_OUTMATERIAL_ALTERNATE_EMAILMATERIAL_ALT_ROUTEMATERIAL_AMP_STORIESMATERIAL_ANALYTICSMATERIAL_ANCHORMATERIAL_ANDROIDMATERIAL_ANIMATIONMATERIAL_ANNOUNCEMENTMATERIAL_AODMATERIAL_APARTMENTMATERIAL_APIMATERIAL_APPLEMATERIAL_APPROVALMATERIAL_APPSMATERIAL_APPS_OUTAGEMATERIAL_APP_BLOCKINGMATERIAL_APP_REGISTRATIONMATERIAL_APP_SETTINGS_ALTMATERIAL_APP_SHORTCUTMATERIAL_ARCHITECTUREMATERIAL_ARCHIVEMATERIAL_AREA_CHARTMATERIAL_ARROW_BACKMATERIAL_ARROW_BACK_IOSMATERIAL_ARROW_BACK_IOS_NEWMATERIAL_ARROW_CIRCLE_DOWNMATERIAL_ARROW_CIRCLE_LEFTMATERIAL_ARROW_CIRCLE_RIGHTMATERIAL_ARROW_CIRCLE_UPMATERIAL_ARROW_DOWNWARDMATERIAL_ARROW_DROP_DOWNMATERIAL_ARROW_DROP_DOWN_CIRCLEMATERIAL_ARROW_DROP_UPMATERIAL_ARROW_FORWARDMATERIAL_ARROW_FORWARD_IOSMATERIAL_ARROW_LEFTMATERIAL_ARROW_OUTWARDMATERIAL_ARROW_RIGHTMATERIAL_ARROW_RIGHT_ALTMATERIAL_ARROW_UPWARDMATERIAL_ARTICLEMATERIAL_ART_TRACKMATERIAL_ASPECT_RATIOMATERIAL_ASSESSMENTMATERIAL_ASSIGNMENTMATERIAL_ASSIGNMENT_ADDMATERIAL_ASSIGNMENT_INDMATERIAL_ASSIGNMENT_LATEMATERIAL_ASSIGNMENT_RETURNMATERIAL_ASSIGNMENT_RETURNEDMATERIAL_ASSIGNMENT_TURNED_INMATERIAL_ASSISTANTMATERIAL_ASSISTANT_DIRECTIONMATERIAL_ASSISTANT_NAVIGATIONMATERIAL_ASSISTANT_PHOTOMATERIAL_ASSIST_WALKERMATERIAL_ASSURED_WORKLOADMATERIAL_ATMMATERIAL_ATTACHMENTMATERIAL_ATTACH_EMAILMATERIAL_ATTACH_FILEMATERIAL_ATTACH_MONEYMATERIAL_ATTRACTIONSMATERIAL_ATTRIBUTIONMATERIAL_AUDIOTRACKMATERIAL_AUDIO_FILEMATERIAL_AUTOFPS_SELECTMATERIAL_AUTORENEWMATERIAL_AUTO_AWESOMEMATERIAL_AUTO_AWESOME_MOSAICMATERIAL_AUTO_AWESOME_MOTIONMATERIAL_AUTO_DELETEMATERIAL_AUTO_FIX_HIGHMATERIAL_AUTO_FIX_NORMALMATERIAL_AUTO_FIX_OFFMATERIAL_AUTO_GRAPHMATERIAL_AUTO_MODEMATERIAL_AUTO_STORIESMATERIAL_AV_TIMERMATERIAL_BABY_CHANGING_STATIONMATERIAL_BACKPACKMATERIAL_BACKSPACEMATERIAL_BACKUPMATERIAL_BACKUP_TABLEMATERIAL_BACK_HANDMATERIAL_BADGEMATERIAL_BAKERY_DININGMATERIAL_BALANCEMATERIAL_BALCONYMATERIAL_BALLOTMATERIAL_BARCODE_READERMATERIAL_BAR_CHARTMATERIAL_BATCH_PREDICTIONMATERIAL_BATHROOMMATERIAL_BATHTUBMATERIAL_BATTERY_0_BARMATERIAL_BATTERY_1_BARMATERIAL_BATTERY_2_BARMATERIAL_BATTERY_3_BARMATERIAL_BATTERY_4_BARMATERIAL_BATTERY_5_BARMATERIAL_BATTERY_6_BARMATERIAL_BATTERY_ALERTMATERIAL_BATTERY_CHARGING_FULLMATERIAL_BATTERY_FULLMATERIAL_BATTERY_SAVERMATERIAL_BATTERY_STDMATERIAL_BATTERY_UNKNOWNMATERIAL_BEACH_ACCESSMATERIAL_BEDMATERIAL_BEDROOM_BABYMATERIAL_BEDROOM_CHILDMATERIAL_BEDROOM_PARENTMATERIAL_BEDTIMEMATERIAL_BEDTIME_OFFMATERIAL_BEENHEREMATERIAL_BENTOMATERIAL_BIKE_SCOOTERMATERIAL_BIOTECHMATERIAL_BLENDERMATERIAL_BLINDMATERIAL_BLINDSMATERIAL_BLINDS_CLOSEDMATERIAL_BLOCKMATERIAL_BLOCK_FLIPPEDMATERIAL_BLOODTYPEMATERIAL_BLUETOOTHMATERIAL_BLUETOOTH_AUDIOMATERIAL_BLUETOOTH_CONNECTEDMATERIAL_BLUETOOTH_DISABLEDMATERIAL_BLUETOOTH_DRIVEMATERIAL_BLUETOOTH_SEARCHINGMATERIAL_BLUR_CIRCULARMATERIAL_BLUR_LINEARMATERIAL_BLUR_OFFMATERIAL_BLUR_ONMATERIAL_BOLTMATERIAL_BOOKMATERIAL_BOOKMARKMATERIAL_BOOKMARKSMATERIAL_BOOKMARK_ADDMATERIAL_BOOKMARK_ADDEDMATERIAL_BOOKMARK_BORDERMATERIAL_BOOKMARK_OUTLINEMATERIAL_BOOKMARK_REMOVEMATERIAL_BOOK_ONLINEMATERIAL_BORDER_ALLMATERIAL_BORDER_BOTTOMMATERIAL_BORDER_CLEARMATERIAL_BORDER_COLORMATERIAL_BORDER_HORIZONTALMATERIAL_BORDER_INNERMATERIAL_BORDER_LEFTMATERIAL_BORDER_OUTERMATERIAL_BORDER_RIGHTMATERIAL_BORDER_STYLEMATERIAL_BORDER_TOPMATERIAL_BORDER_VERTICALMATERIAL_BOYMATERIAL_BRANDING_WATERMARKMATERIAL_BREAKFAST_DININGMATERIAL_BRIGHTNESS_1MATERIAL_BRIGHTNESS_2MATERIAL_BRIGHTNESS_3MATERIAL_BRIGHTNESS_4MATERIAL_BRIGHTNESS_5MATERIAL_BRIGHTNESS_6MATERIAL_BRIGHTNESS_7MATERIAL_BRIGHTNESS_AUTOMATERIAL_BRIGHTNESS_HIGHMATERIAL_BRIGHTNESS_LOWMATERIAL_BRIGHTNESS_MEDIUMMATERIAL_BROADCAST_ON_HOMEMATERIAL_BROADCAST_ON_PERSONALMATERIAL_BROKEN_IMAGEMATERIAL_BROWSER_NOT_SUPPORTEDMATERIAL_BROWSER_UPDATEDMATERIAL_BROWSE_GALLERYMATERIAL_BRUNCH_DININGMATERIAL_BRUSHMATERIAL_BUBBLE_CHARTMATERIAL_BUG_REPORTMATERIAL_BUILDMATERIAL_BUILD_CIRCLEMATERIAL_BUNGALOWMATERIAL_BURST_MODEMATERIAL_BUSINESSMATERIAL_BUSINESS_CENTERMATERIAL_BUS_ALERTMATERIAL_CABINMATERIAL_CABLEMATERIAL_CACHEDMATERIAL_CAKEMATERIAL_CALCULATEMATERIAL_CALENDAR_MONTHMATERIAL_CALENDAR_TODAYMATERIAL_CALENDAR_VIEW_DAYMATERIAL_CALENDAR_VIEW_MONTHMATERIAL_CALENDAR_VIEW_WEEKMATERIAL_CALLMATERIAL_CALL_ENDMATERIAL_CALL_MADEMATERIAL_CALL_MERGEMATERIAL_CALL_MISSEDMATERIAL_CALL_MISSED_OUTGOINGMATERIAL_CALL_RECEIVEDMATERIAL_CALL_SPLITMATERIAL_CALL_TO_ACTIONMATERIAL_CAMERAMATERIAL_CAMERASWITCHMATERIAL_CAMERA_ALTMATERIAL_CAMERA_ENHANCEMATERIAL_CAMERA_FRONTMATERIAL_CAMERA_INDOORMATERIAL_CAMERA_OUTDOORMATERIAL_CAMERA_REARMATERIAL_CAMERA_ROLLMATERIAL_CAMPAIGNMATERIAL_CANCELMATERIAL_CANCEL_PRESENTATIONMATERIAL_CANCEL_SCHEDULE_SENDMATERIAL_CANDLESTICK_CHARTMATERIAL_CARD_GIFTCARDMATERIAL_CARD_MEMBERSHIPMATERIAL_CARD_TRAVELMATERIAL_CARPENTERMATERIAL_CAR_CRASHMATERIAL_CAR_RENTALMATERIAL_CAR_REPAIRMATERIAL_CASESMATERIAL_CASINOMATERIAL_CASTMATERIAL_CASTLEMATERIAL_CAST_CONNECTEDMATERIAL_CAST_FOR_EDUCATIONMATERIAL_CATCHING_POKEMONMATERIAL_CATEGORYMATERIAL_CELEBRATIONMATERIAL_CELL_TOWERMATERIAL_CELL_WIFIMATERIAL_CENTER_FOCUS_STRONGMATERIAL_CENTER_FOCUS_WEAKMATERIAL_CHAIRMATERIAL_CHAIR_ALTMATERIAL_CHALETMATERIAL_CHANGE_CIRCLEMATERIAL_CHANGE_HISTORYMATERIAL_CHARGING_STATIONMATERIAL_CHATMATERIAL_CHAT_BUBBLEMATERIAL_CHAT_BUBBLE_OUTLINEMATERIAL_CHECKMATERIAL_CHECKLISTMATERIAL_CHECKLIST_RTLMATERIAL_CHECKROOMMATERIAL_CHECK_BOXMATERIAL_CHECK_BOX_OUTLINE_BLANKMATERIAL_CHECK_CIRCLEMATERIAL_CHECK_CIRCLE_OUTLINEMATERIAL_CHEVRON_LEFTMATERIAL_CHEVRON_RIGHTMATERIAL_CHILD_CAREMATERIAL_CHILD_FRIENDLYMATERIAL_CHROME_READER_MODEMATERIAL_CHURCHMATERIAL_CIRCLEMATERIAL_CIRCLE_NOTIFICATIONSMATERIAL_CLASSMATERIAL_CLEANING_SERVICESMATERIAL_CLEAN_HANDSMATERIAL_CLEARMATERIAL_CLEAR_ALLMATERIAL_CLOSEMATERIAL_CLOSED_CAPTIONMATERIAL_CLOSED_CAPTION_DISABLEDMATERIAL_CLOSED_CAPTION_OFFMATERIAL_CLOSE_FULLSCREENMATERIAL_CLOUDMATERIAL_CLOUDY_SNOWINGMATERIAL_CLOUD_CIRCLEMATERIAL_CLOUD_DONEMATERIAL_CLOUD_DOWNLOADMATERIAL_CLOUD_OFFMATERIAL_CLOUD_QUEUEMATERIAL_CLOUD_SYNCMATERIAL_CLOUD_UPLOADMATERIAL_CO2MATERIAL_CODEMATERIAL_CODE_OFFMATERIAL_COFFEEMATERIAL_COFFEE_MAKERMATERIAL_COLLECTIONSMATERIAL_COLLECTIONS_BOOKMARKMATERIAL_COLORIZEMATERIAL_COLOR_LENSMATERIAL_COMMENTMATERIAL_COMMENTS_DISABLEDMATERIAL_COMMENT_BANKMATERIAL_COMMITMATERIAL_COMMUTEMATERIAL_COMPAREMATERIAL_COMPARE_ARROWSMATERIAL_COMPASS_CALIBRATIONMATERIAL_COMPOSTMATERIAL_COMPRESSMATERIAL_COMPUTERMATERIAL_CONFIRMATION_NUMMATERIAL_CONFIRMATION_NUMBERMATERIAL_CONNECTED_TVMATERIAL_CONNECTING_AIRPORTSMATERIAL_CONNECT_WITHOUT_CONTACTMATERIAL_CONSTRUCTIONMATERIAL_CONTACTLESSMATERIAL_CONTACTSMATERIAL_CONTACT_EMERGENCYMATERIAL_CONTACT_MAILMATERIAL_CONTACT_PAGEMATERIAL_CONTACT_PHONEMATERIAL_CONTACT_SUPPORTMATERIAL_CONTENT_COPYMATERIAL_CONTENT_CUTMATERIAL_CONTENT_PASTEMATERIAL_CONTENT_PASTE_GOMATERIAL_CONTENT_PASTE_OFFMATERIAL_CONTENT_PASTE_SEARCHMATERIAL_CONTRASTMATERIAL_CONTROL_CAMERAMATERIAL_CONTROL_POINTMATERIAL_CONTROL_POINT_DUPLICATEMATERIAL_CONVEYOR_BELTMATERIAL_COOKIEMATERIAL_COPYRIGHTMATERIAL_COPY_ALLMATERIAL_CORONAVIRUSMATERIAL_CORPORATE_FAREMATERIAL_COTTAGEMATERIAL_COUNTERTOPSMATERIAL_CO_PRESENTMATERIAL_CREATEMATERIAL_CREATE_NEW_FOLDERMATERIAL_CREDIT_CARDMATERIAL_CREDIT_CARD_OFFMATERIAL_CREDIT_SCOREMATERIAL_CRIBMATERIAL_CRISIS_ALERTMATERIAL_CROPMATERIAL_CROP_16_9MATERIAL_CROP_3_2MATERIAL_CROP_5_4MATERIAL_CROP_7_5MATERIAL_CROP_DINMATERIAL_CROP_FREEMATERIAL_CROP_LANDSCAPEMATERIAL_CROP_ORIGINALMATERIAL_CROP_PORTRAITMATERIAL_CROP_ROTATEMATERIAL_CROP_SQUAREMATERIAL_CRUELTY_FREEMATERIAL_CSSMATERIAL_CURRENCY_BITCOINMATERIAL_CURRENCY_EXCHANGEMATERIAL_CURRENCY_FRANCMATERIAL_CURRENCY_LIRAMATERIAL_CURRENCY_POUNDMATERIAL_CURRENCY_RUBLEMATERIAL_CURRENCY_RUPEEMATERIAL_CURRENCY_YENMATERIAL_CURRENCY_YUANMATERIAL_CURTAINSMATERIAL_CURTAINS_CLOSEDMATERIAL_CYCLONEMATERIAL_DANGEROUSMATERIAL_DARK_MODEMATERIAL_DASHBOARDMATERIAL_DASHBOARD_CUSTOMIZEMATERIAL_DATASETMATERIAL_DATASET_LINKEDMATERIAL_DATA_ARRAYMATERIAL_DATA_EXPLORATIONMATERIAL_DATA_OBJECTMATERIAL_DATA_SAVER_OFFMATERIAL_DATA_SAVER_ONMATERIAL_DATA_THRESHOLDINGMATERIAL_DATA_USAGEMATERIAL_DATE_RANGEMATERIAL_DEBLURMATERIAL_DECKMATERIAL_DEHAZEMATERIAL_DELETEMATERIAL_DELETE_FOREVERMATERIAL_DELETE_OUTLINEMATERIAL_DELETE_SWEEPMATERIAL_DELIVERY_DININGMATERIAL_DENSITY_LARGEMATERIAL_DENSITY_MEDIUMMATERIAL_DENSITY_SMALLMATERIAL_DEPARTURE_BOARDMATERIAL_DESCRIPTIONMATERIAL_DESELECTMATERIAL_DESIGN_SERVICESMATERIAL_DESKMATERIAL_DESKTOP_ACCESS_DISABLEDMATERIAL_DESKTOP_MACMATERIAL_DESKTOP_WINDOWSMATERIAL_DETAILSMATERIAL_DEVELOPER_BOARDMATERIAL_DEVELOPER_BOARD_OFFMATERIAL_DEVELOPER_MODEMATERIAL_DEVICESMATERIAL_DEVICES_FOLDMATERIAL_DEVICES_OTHERMATERIAL_DEVICE_HUBMATERIAL_DEVICE_THERMOSTATMATERIAL_DEVICE_UNKNOWNMATERIAL_DEW_POINTMATERIAL_DIALER_SIPMATERIAL_DIALPADMATERIAL_DIAMONDMATERIAL_DIFFERENCEMATERIAL_DININGMATERIAL_DINNER_DININGMATERIAL_DIRECTIONSMATERIAL_DIRECTIONS_BIKEMATERIAL_DIRECTIONS_BOATMATERIAL_DIRECTIONS_BOAT_FILLEDMATERIAL_DIRECTIONS_BUSMATERIAL_DIRECTIONS_BUS_FILLEDMATERIAL_DIRECTIONS_CARMATERIAL_DIRECTIONS_CAR_FILLEDMATERIAL_DIRECTIONS_FERRYMATERIAL_DIRECTIONS_OFFMATERIAL_DIRECTIONS_RAILWAYMATERIAL_DIRECTIONS_RAILWAY_FILLEDMATERIAL_DIRECTIONS_RUNMATERIAL_DIRECTIONS_SUBWAYMATERIAL_DIRECTIONS_SUBWAY_FILLEDMATERIAL_DIRECTIONS_TRAINMATERIAL_DIRECTIONS_TRANSITMATERIAL_DIRECTIONS_TRANSIT_FILLEDMATERIAL_DIRECTIONS_WALKMATERIAL_DIRTY_LENSMATERIAL_DISABLED_BY_DEFAULTMATERIAL_DISABLED_VISIBLEMATERIAL_DISCORDMATERIAL_DISCOUNTMATERIAL_DISC_FULLMATERIAL_DISPLAY_SETTINGSMATERIAL_DIVERSITY_1MATERIAL_DIVERSITY_2MATERIAL_DIVERSITY_3MATERIAL_DND_FORWARDSLASHMATERIAL_DNSMATERIAL_DOCKMATERIAL_DOCUMENT_SCANNERMATERIAL_DOMAINMATERIAL_DOMAIN_ADDMATERIAL_DOMAIN_DISABLEDMATERIAL_DOMAIN_VERIFICATIONMATERIAL_DONEMATERIAL_DONE_ALLMATERIAL_DONE_OUTLINEMATERIAL_DONUT_LARGEMATERIAL_DONUT_SMALLMATERIAL_DOORBELLMATERIAL_DOOR_BACKMATERIAL_DOOR_FRONTMATERIAL_DOOR_SLIDINGMATERIAL_DOUBLE_ARROWMATERIAL_DOWNHILL_SKIINGMATERIAL_DOWNLOADMATERIAL_DOWNLOADINGMATERIAL_DOWNLOAD_DONEMATERIAL_DOWNLOAD_FOR_OFFLINEMATERIAL_DO_DISTURBMATERIAL_DO_DISTURB_ALTMATERIAL_DO_DISTURB_OFFMATERIAL_DO_DISTURB_ONMATERIAL_DO_NOT_DISTURBMATERIAL_DO_NOT_DISTURB_ALTMATERIAL_DO_NOT_DISTURB_OFFMATERIAL_DO_NOT_DISTURB_ONMATERIAL_DO_NOT_DISTURB_ON_TOTAL_SILENCEMATERIAL_DO_NOT_STEPMATERIAL_DO_NOT_TOUCHMATERIAL_DRAFTSMATERIAL_DRAG_HANDLEMATERIAL_DRAG_INDICATORMATERIAL_DRAWMATERIAL_DRIVE_ETAMATERIAL_DRIVE_FILE_MOVEMATERIAL_DRIVE_FILE_MOVE_OUTLINEMATERIAL_DRIVE_FILE_MOVE_RTLMATERIAL_DRIVE_FILE_RENAME_OUTLINEMATERIAL_DRIVE_FOLDER_UPLOADMATERIAL_DRYMATERIAL_DRY_CLEANINGMATERIAL_DUOMATERIAL_DVRMATERIAL_DYNAMIC_FEEDMATERIAL_DYNAMIC_FORMMATERIAL_EARBUDSMATERIAL_EARBUDS_BATTERYMATERIAL_EASTMATERIAL_ECOMATERIAL_EDGESENSOR_HIGHMATERIAL_EDGESENSOR_LOWMATERIAL_EDITMATERIAL_EDIT_ATTRIBUTESMATERIAL_EDIT_CALENDARMATERIAL_EDIT_DOCUMENTMATERIAL_EDIT_LOCATIONMATERIAL_EDIT_LOCATION_ALTMATERIAL_EDIT_NOTEMATERIAL_EDIT_NOTIFICATIONSMATERIAL_EDIT_OFFMATERIAL_EDIT_ROADMATERIAL_EDIT_SQUAREMATERIAL_EGGMATERIAL_EGG_ALTMATERIAL_EJECTMATERIAL_ELDERLYMATERIAL_ELDERLY_WOMANMATERIAL_ELECTRICAL_SERVICESMATERIAL_ELECTRIC_BIKEMATERIAL_ELECTRIC_BOLTMATERIAL_ELECTRIC_CARMATERIAL_ELECTRIC_METERMATERIAL_ELECTRIC_MOPEDMATERIAL_ELECTRIC_RICKSHAWMATERIAL_ELECTRIC_SCOOTERMATERIAL_ELEVATORMATERIAL_EMAILMATERIAL_EMERGENCYMATERIAL_EMERGENCY_RECORDINGMATERIAL_EMERGENCY_SHAREMATERIAL_EMOJI_EMOTIONSMATERIAL_EMOJI_EVENTSMATERIAL_EMOJI_FLAGSMATERIAL_EMOJI_FOOD_BEVERAGEMATERIAL_EMOJI_NATUREMATERIAL_EMOJI_OBJECTSMATERIAL_EMOJI_PEOPLEMATERIAL_EMOJI_SYMBOLSMATERIAL_EMOJI_TRANSPORTATIONMATERIAL_ENERGY_SAVINGS_LEAFMATERIAL_ENGINEERINGMATERIAL_ENHANCED_ENCRYPTIONMATERIAL_ENHANCE_PHOTO_TRANSLATEMATERIAL_EQUALIZERMATERIAL_ERRORMATERIAL_ERROR_OUTLINEMATERIAL_ESCALATORMATERIAL_ESCALATOR_WARNINGMATERIAL_EUROMATERIAL_EURO_SYMBOLMATERIAL_EVENTMATERIAL_EVENT_AVAILABLEMATERIAL_EVENT_BUSYMATERIAL_EVENT_NOTEMATERIAL_EVENT_REPEATMATERIAL_EVENT_SEATMATERIAL_EV_STATIONMATERIAL_EXIT_TO_APPMATERIAL_EXPANDMATERIAL_EXPAND_CIRCLE_DOWNMATERIAL_EXPAND_LESSMATERIAL_EXPAND_MOREMATERIAL_EXPLICITMATERIAL_EXPLOREMATERIAL_EXPLORE_OFFMATERIAL_EXPOSUREMATERIAL_EXPOSURE_MINUS_1MATERIAL_EXPOSURE_MINUS_2MATERIAL_EXPOSURE_NEG_1MATERIAL_EXPOSURE_NEG_2MATERIAL_EXPOSURE_PLUS_1MATERIAL_EXPOSURE_PLUS_2MATERIAL_EXPOSURE_ZEROMATERIAL_EXTENSIONMATERIAL_EXTENSION_OFFMATERIAL_E_MOBILEDATAMATERIAL_FACEMATERIAL_FACEBOOKMATERIAL_FACE_2MATERIAL_FACE_3MATERIAL_FACE_4MATERIAL_FACE_5MATERIAL_FACE_6MATERIAL_FACE_RETOUCHING_NATURALMATERIAL_FACE_RETOUCHING_OFFMATERIAL_FACTORYMATERIAL_FACT_CHECKMATERIAL_FAMILY_RESTROOMMATERIAL_FASTFOODMATERIAL_FAST_FORWARDMATERIAL_FAST_REWINDMATERIAL_FAVORITEMATERIAL_FAVORITE_BORDERMATERIAL_FAVORITE_OUTLINEMATERIAL_FAXMATERIAL_FEATURED_PLAY_LISTMATERIAL_FEATURED_VIDEOMATERIAL_FEEDMATERIAL_FEEDBACKMATERIAL_FEMALEMATERIAL_FENCEMATERIAL_FESTIVALMATERIAL_FIBER_DVRMATERIAL_FIBER_MANUAL_RECORDMATERIAL_FIBER_NEWMATERIAL_FIBER_PINMATERIAL_FIBER_SMART_RECORDMATERIAL_FILE_COPYMATERIAL_FILE_DOWNLOADMATERIAL_FILE_DOWNLOAD_DONEMATERIAL_FILE_DOWNLOAD_OFFMATERIAL_FILE_OPENMATERIAL_FILE_PRESENTMATERIAL_FILE_UPLOADMATERIAL_FILE_UPLOAD_OFFMATERIAL_FILTERMATERIAL_FILTER_1MATERIAL_FILTER_2MATERIAL_FILTER_3MATERIAL_FILTER_4MATERIAL_FILTER_5MATERIAL_FILTER_6MATERIAL_FILTER_7MATERIAL_FILTER_8MATERIAL_FILTER_9MATERIAL_FILTER_9_PLUSMATERIAL_FILTER_ALTMATERIAL_FILTER_ALT_OFFMATERIAL_FILTER_B_AND_WMATERIAL_FILTER_CENTER_FOCUSMATERIAL_FILTER_DRAMAMATERIAL_FILTER_FRAMESMATERIAL_FILTER_HDRMATERIAL_FILTER_LISTMATERIAL_FILTER_LIST_ALTMATERIAL_FILTER_LIST_OFFMATERIAL_FILTER_NONEMATERIAL_FILTER_TILT_SHIFTMATERIAL_FILTER_VINTAGEMATERIAL_FIND_IN_PAGEMATERIAL_FIND_REPLACEMATERIAL_FINGERPRINTMATERIAL_FIREPLACEMATERIAL_FIRE_EXTINGUISHERMATERIAL_FIRE_HYDRANTMATERIAL_FIRE_HYDRANT_ALTMATERIAL_FIRE_TRUCKMATERIAL_FIRST_PAGEMATERIAL_FITBITMATERIAL_FITNESS_CENTERMATERIAL_FIT_SCREENMATERIAL_FLAGMATERIAL_FLAG_CIRCLEMATERIAL_FLAKYMATERIAL_FLAREMATERIAL_FLASHLIGHT_OFFMATERIAL_FLASHLIGHT_ONMATERIAL_FLASH_AUTOMATERIAL_FLASH_OFFMATERIAL_FLASH_ONMATERIAL_FLATWAREMATERIAL_FLIGHTMATERIAL_FLIGHT_CLASSMATERIAL_FLIGHT_LANDMATERIAL_FLIGHT_TAKEOFFMATERIAL_FLIPMATERIAL_FLIP_CAMERA_ANDROIDMATERIAL_FLIP_CAMERA_IOSMATERIAL_FLIP_TO_BACKMATERIAL_FLIP_TO_FRONTMATERIAL_FLOODMATERIAL_FLOURESCENTMATERIAL_FLUORESCENTMATERIAL_FLUTTER_DASHMATERIAL_FMD_BADMATERIAL_FMD_GOODMATERIAL_FOGGYMATERIAL_FOLDERMATERIAL_FOLDER_COPYMATERIAL_FOLDER_DELETEMATERIAL_FOLDER_OFFMATERIAL_FOLDER_OPENMATERIAL_FOLDER_SHAREDMATERIAL_FOLDER_SPECIALMATERIAL_FOLDER_ZIPMATERIAL_FOLLOW_THE_SIGNSMATERIAL_FONT_DOWNLOADMATERIAL_FONT_DOWNLOAD_OFFMATERIAL_FOOD_BANKMATERIAL_FORESTMATERIAL_FORKLIFTMATERIAL_FORK_LEFTMATERIAL_FORK_RIGHTMATERIAL_FORMAT_ALIGN_CENTERMATERIAL_FORMAT_ALIGN_JUSTIFYMATERIAL_FORMAT_ALIGN_LEFTMATERIAL_FORMAT_ALIGN_RIGHTMATERIAL_FORMAT_BOLDMATERIAL_FORMAT_CLEARMATERIAL_FORMAT_COLOR_FILLMATERIAL_FORMAT_COLOR_RESETMATERIAL_FORMAT_COLOR_TEXTMATERIAL_FORMAT_INDENT_DECREASEMATERIAL_FORMAT_INDENT_INCREASEMATERIAL_FORMAT_ITALICMATERIAL_FORMAT_LINE_SPACINGMATERIAL_FORMAT_LIST_BULLETEDMATERIAL_FORMAT_LIST_BULLETED_ADDMATERIAL_FORMAT_LIST_NUMBEREDMATERIAL_FORMAT_LIST_NUMBERED_RTLMATERIAL_FORMAT_OVERLINEMATERIAL_FORMAT_PAINTMATERIAL_FORMAT_QUOTEMATERIAL_FORMAT_SHAPESMATERIAL_FORMAT_SIZEMATERIAL_FORMAT_STRIKETHROUGHMATERIAL_FORMAT_TEXTDIRECTION_L_TO_RMATERIAL_FORMAT_TEXTDIRECTION_R_TO_LMATERIAL_FORMAT_UNDERLINEMATERIAL_FORMAT_UNDERLINEDMATERIAL_FORTMATERIAL_FORUMMATERIAL_FORWARDMATERIAL_FORWARD_10MATERIAL_FORWARD_30MATERIAL_FORWARD_5MATERIAL_FORWARD_TO_INBOXMATERIAL_FOUNDATIONMATERIAL_FREE_BREAKFASTMATERIAL_FREE_CANCELLATIONMATERIAL_FRONT_HANDMATERIAL_FRONT_LOADERMATERIAL_FULLSCREENMATERIAL_FULLSCREEN_EXITMATERIAL_FUNCTIONSMATERIAL_GAMEPADMATERIAL_GAMESMATERIAL_GARAGEMATERIAL_GAS_METERMATERIAL_GAVELMATERIAL_GENERATING_TOKENSMATERIAL_GESTUREMATERIAL_GET_APPMATERIAL_GIFMATERIAL_GIF_BOXMATERIAL_GIRLMATERIAL_GITEMATERIAL_GOLF_COURSEMATERIAL_GPP_BADMATERIAL_GPP_GOODMATERIAL_GPP_MAYBEMATERIAL_GPS_FIXEDMATERIAL_GPS_NOT_FIXEDMATERIAL_GPS_OFFMATERIAL_GRADEMATERIAL_GRADIENTMATERIAL_GRADINGMATERIAL_GRAINMATERIAL_GRAPHIC_EQMATERIAL_GRASSMATERIAL_GRID_3X3MATERIAL_GRID_4X4MATERIAL_GRID_GOLDENRATIOMATERIAL_GRID_OFFMATERIAL_GRID_ONMATERIAL_GRID_VIEWMATERIAL_GROUPMATERIAL_GROUPSMATERIAL_GROUPS_2MATERIAL_GROUPS_3MATERIAL_GROUP_ADDMATERIAL_GROUP_OFFMATERIAL_GROUP_REMOVEMATERIAL_GROUP_WORKMATERIAL_G_MOBILEDATAMATERIAL_G_TRANSLATEMATERIAL_HAILMATERIAL_HANDSHAKEMATERIAL_HANDYMANMATERIAL_HARDWAREMATERIAL_HDMATERIAL_HDR_AUTOMATERIAL_HDR_AUTO_SELECTMATERIAL_HDR_ENHANCED_SELECTMATERIAL_HDR_OFFMATERIAL_HDR_OFF_SELECTMATERIAL_HDR_ONMATERIAL_HDR_ON_SELECTMATERIAL_HDR_PLUSMATERIAL_HDR_STRONGMATERIAL_HDR_WEAKMATERIAL_HEADPHONESMATERIAL_HEADPHONES_BATTERYMATERIAL_HEADSETMATERIAL_HEADSET_MICMATERIAL_HEADSET_OFFMATERIAL_HEALINGMATERIAL_HEALTH_AND_SAFETYMATERIAL_HEARINGMATERIAL_HEARING_DISABLEDMATERIAL_HEART_BROKENMATERIAL_HEAT_PUMPMATERIAL_HEIGHTMATERIAL_HELPMATERIAL_HELP_CENTERMATERIAL_HELP_OUTLINEMATERIAL_HEVCMATERIAL_HEXAGONMATERIAL_HIDE_IMAGEMATERIAL_HIDE_SOURCEMATERIAL_HIGHLIGHTMATERIAL_HIGHLIGHT_ALTMATERIAL_HIGHLIGHT_OFFMATERIAL_HIGHLIGHT_REMOVEMATERIAL_HIGH_QUALITYMATERIAL_HIKINGMATERIAL_HISTORYMATERIAL_HISTORY_EDUMATERIAL_HISTORY_TOGGLE_OFFMATERIAL_HIVEMATERIAL_HLSMATERIAL_HLS_OFFMATERIAL_HOLIDAY_VILLAGEMATERIAL_HOMEMATERIAL_HOME_FILLEDMATERIAL_HOME_MAXMATERIAL_HOME_MINIMATERIAL_HOME_REPAIR_SERVICEMATERIAL_HOME_WORKMATERIAL_HORIZONTAL_DISTRIBUTEMATERIAL_HORIZONTAL_RULEMATERIAL_HORIZONTAL_SPLITMATERIAL_HOTELMATERIAL_HOTEL_CLASSMATERIAL_HOT_TUBMATERIAL_HOURGLASS_BOTTOMMATERIAL_HOURGLASS_DISABLEDMATERIAL_HOURGLASS_EMPTYMATERIAL_HOURGLASS_FULLMATERIAL_HOURGLASS_TOPMATERIAL_HOUSEMATERIAL_HOUSEBOATMATERIAL_HOUSE_SIDINGMATERIAL_HOW_TO_REGMATERIAL_HOW_TO_VOTEMATERIAL_HTMLMATERIAL_HTTPMATERIAL_HTTPSMATERIAL_HUBMATERIAL_HVACMATERIAL_H_MOBILEDATAMATERIAL_H_PLUS_MOBILEDATAMATERIAL_ICECREAMMATERIAL_ICE_SKATINGMATERIAL_IMAGEMATERIAL_IMAGESEARCH_ROLLERMATERIAL_IMAGE_ASPECT_RATIOMATERIAL_IMAGE_NOT_SUPPORTEDMATERIAL_IMAGE_SEARCHMATERIAL_IMPORTANT_DEVICESMATERIAL_IMPORT_CONTACTSMATERIAL_IMPORT_EXPORTMATERIAL_INBOXMATERIAL_INCOMPLETE_CIRCLEMATERIAL_INDETERMINATE_CHECK_BOXMATERIAL_INFOMATERIAL_INFO_OUTLINEMATERIAL_INPUTMATERIAL_INSERT_CHARTMATERIAL_INSERT_CHART_OUTLINEDMATERIAL_INSERT_COMMENTMATERIAL_INSERT_DRIVE_FILEMATERIAL_INSERT_EMOTICONMATERIAL_INSERT_INVITATIONMATERIAL_INSERT_LINKMATERIAL_INSERT_PAGE_BREAKMATERIAL_INSERT_PHOTOMATERIAL_INSIGHTSMATERIAL_INSTALL_DESKTOPMATERIAL_INSTALL_MOBILEMATERIAL_INTEGRATION_INSTRUCTIONSMATERIAL_INTERESTSMATERIAL_INTERPRETER_MODEMATERIAL_INVENTORYMATERIAL_INVENTORY_2MATERIAL_INVERT_COLORSMATERIAL_INVERT_COLORS_OFFMATERIAL_INVERT_COLORS_ONMATERIAL_IOS_SHAREMATERIAL_IRONMATERIAL_ISOMATERIAL_JAVASCRIPTMATERIAL_JOIN_FULLMATERIAL_JOIN_INNERMATERIAL_JOIN_LEFTMATERIAL_JOIN_RIGHTMATERIAL_KAYAKINGMATERIAL_KEBAB_DININGMATERIAL_KEYMATERIAL_KEYBOARDMATERIAL_KEYBOARD_ALTMATERIAL_KEYBOARD_ARROW_DOWNMATERIAL_KEYBOARD_ARROW_LEFTMATERIAL_KEYBOARD_ARROW_RIGHTMATERIAL_KEYBOARD_ARROW_UPMATERIAL_KEYBOARD_BACKSPACEMATERIAL_KEYBOARD_CAPSLOCKMATERIAL_KEYBOARD_COMMANDMATERIAL_KEYBOARD_COMMAND_KEYMATERIAL_KEYBOARD_CONTROLMATERIAL_KEYBOARD_CONTROL_KEYMATERIAL_KEYBOARD_DOUBLE_ARROW_DOWNMATERIAL_KEYBOARD_DOUBLE_ARROW_LEFTMATERIAL_KEYBOARD_DOUBLE_ARROW_RIGHTMATERIAL_KEYBOARD_DOUBLE_ARROW_UPMATERIAL_KEYBOARD_HIDEMATERIAL_KEYBOARD_OPTIONMATERIAL_KEYBOARD_OPTION_KEYMATERIAL_KEYBOARD_RETURNMATERIAL_KEYBOARD_TABMATERIAL_KEYBOARD_VOICEMATERIAL_KEY_OFFMATERIAL_KING_BEDMATERIAL_KITCHENMATERIAL_KITESURFINGMATERIAL_LABELMATERIAL_LABEL_IMPORTANTMATERIAL_LABEL_IMPORTANT_OUTLINEMATERIAL_LABEL_OFFMATERIAL_LABEL_OUTLINEMATERIAL_LANMATERIAL_LANDSCAPEMATERIAL_LANDSLIDEMATERIAL_LANGUAGEMATERIAL_LAPTOPMATERIAL_LAPTOP_CHROMEBOOKMATERIAL_LAPTOP_MACMATERIAL_LAPTOP_WINDOWSMATERIAL_LAST_PAGEMATERIAL_LAUNCHMATERIAL_LAYERSMATERIAL_LAYERS_CLEARMATERIAL_LEADERBOARDMATERIAL_LEAK_ADDMATERIAL_LEAK_REMOVEMATERIAL_LEAVE_BAGS_AT_HOMEMATERIAL_LEGEND_TOGGLEMATERIAL_LENSMATERIAL_LENS_BLURMATERIAL_LIBRARY_ADDMATERIAL_LIBRARY_ADD_CHECKMATERIAL_LIBRARY_BOOKSMATERIAL_LIBRARY_MUSICMATERIAL_LIGHTMATERIAL_LIGHTBULBMATERIAL_LIGHTBULB_CIRCLEMATERIAL_LIGHTBULB_OUTLINEMATERIAL_LIGHT_MODEMATERIAL_LINEAR_SCALEMATERIAL_LINE_AXISMATERIAL_LINE_STYLEMATERIAL_LINE_WEIGHTMATERIAL_LINKMATERIAL_LINKED_CAMERAMATERIAL_LINK_OFFMATERIAL_LIQUORMATERIAL_LISTMATERIAL_LIST_ALTMATERIAL_LIVE_HELPMATERIAL_LIVE_TVMATERIAL_LIVINGMATERIAL_LOCAL_ACTIVITYMATERIAL_LOCAL_AIRPORTMATERIAL_LOCAL_ATMMATERIAL_LOCAL_ATTRACTIONMATERIAL_LOCAL_BARMATERIAL_LOCAL_CAFEMATERIAL_LOCAL_CAR_WASHMATERIAL_LOCAL_CONVENIENCE_STOREMATERIAL_LOCAL_DININGMATERIAL_LOCAL_DRINKMATERIAL_LOCAL_FIRE_DEPARTMENTMATERIAL_LOCAL_FLORISTMATERIAL_LOCAL_GAS_STATIONMATERIAL_LOCAL_GROCERY_STOREMATERIAL_LOCAL_HOSPITALMATERIAL_LOCAL_HOTELMATERIAL_LOCAL_LAUNDRY_SERVICEMATERIAL_LOCAL_LIBRARYMATERIAL_LOCAL_MALLMATERIAL_LOCAL_MOVIESMATERIAL_LOCAL_OFFERMATERIAL_LOCAL_PARKINGMATERIAL_LOCAL_PHARMACYMATERIAL_LOCAL_PHONEMATERIAL_LOCAL_PIZZAMATERIAL_LOCAL_PLAYMATERIAL_LOCAL_POLICEMATERIAL_LOCAL_POST_OFFICEMATERIAL_LOCAL_PRINTSHOPMATERIAL_LOCAL_PRINT_SHOPMATERIAL_LOCAL_RESTAURANTMATERIAL_LOCAL_SEEMATERIAL_LOCAL_SHIPPINGMATERIAL_LOCAL_TAXIMATERIAL_LOCATION_CITYMATERIAL_LOCATION_DISABLEDMATERIAL_LOCATION_HISTORYMATERIAL_LOCATION_OFFMATERIAL_LOCATION_ONMATERIAL_LOCATION_PINMATERIAL_LOCATION_SEARCHINGMATERIAL_LOCKMATERIAL_LOCK_CLOCKMATERIAL_LOCK_OPENMATERIAL_LOCK_OUTLINEMATERIAL_LOCK_PERSONMATERIAL_LOCK_RESETMATERIAL_LOGINMATERIAL_LOGOUTMATERIAL_LOGO_DEVMATERIAL_LOOKSMATERIAL_LOOKS_3MATERIAL_LOOKS_4MATERIAL_LOOKS_5MATERIAL_LOOKS_6MATERIAL_LOOKS_ONEMATERIAL_LOOKS_TWOMATERIAL_LOOPMATERIAL_LOUPEMATERIAL_LOW_PRIORITYMATERIAL_LOYALTYMATERIAL_LTE_MOBILEDATAMATERIAL_LTE_PLUS_MOBILEDATAMATERIAL_LUGGAGEMATERIAL_LUNCH_DININGMATERIAL_LYRICSMATERIAL_MACRO_OFFMATERIAL_MAILMATERIAL_MAIL_LOCKMATERIAL_MAIL_OUTLINEMATERIAL_MALEMATERIAL_MANMATERIAL_MANAGE_ACCOUNTSMATERIAL_MANAGE_HISTORYMATERIAL_MANAGE_SEARCHMATERIAL_MAN_2MATERIAL_MAN_3MATERIAL_MAN_4MATERIAL_MAPMATERIAL_MAPS_HOME_WORKMATERIAL_MAPS_UGCMATERIAL_MARGINMATERIAL_MARKUNREADMATERIAL_MARKUNREAD_MAILBOXMATERIAL_MARK_AS_UNREADMATERIAL_MARK_CHAT_READMATERIAL_MARK_CHAT_UNREADMATERIAL_MARK_EMAIL_READMATERIAL_MARK_EMAIL_UNREADMATERIAL_MARK_UNREAD_CHAT_ALTMATERIAL_MASKSMATERIAL_MAXIMIZEMATERIAL_MEDIATIONMATERIAL_MEDIA_BLUETOOTH_OFFMATERIAL_MEDIA_BLUETOOTH_ONMATERIAL_MEDICAL_INFORMATIONMATERIAL_MEDICAL_SERVICESMATERIAL_MEDICATIONMATERIAL_MEDICATION_LIQUIDMATERIAL_MEETING_ROOMMATERIAL_MEMORYMATERIAL_MENUMATERIAL_MENU_BOOKMATERIAL_MENU_OPENMATERIAL_MERGEMATERIAL_MERGE_TYPEMATERIAL_MESSAGEMATERIAL_MESSENGERMATERIAL_MESSENGER_OUTLINEMATERIAL_MICMATERIAL_MICROWAVEMATERIAL_MIC_EXTERNAL_OFFMATERIAL_MIC_EXTERNAL_ONMATERIAL_MIC_NONEMATERIAL_MIC_OFFMATERIAL_MILITARY_TECHMATERIAL_MINIMIZEMATERIAL_MINOR_CRASHMATERIAL_MISCELLANEOUS_SERVICESMATERIAL_MISSED_VIDEO_CALLMATERIAL_MMSMATERIAL_MOBILEDATA_OFFMATERIAL_MOBILE_FRIENDLYMATERIAL_MOBILE_OFFMATERIAL_MOBILE_SCREEN_SHAREMATERIAL_MODEMATERIAL_MODEL_TRAININGMATERIAL_MODE_COMMENTMATERIAL_MODE_EDITMATERIAL_MODE_EDIT_OUTLINEMATERIAL_MODE_FAN_OFFMATERIAL_MODE_NIGHTMATERIAL_MODE_OF_TRAVELMATERIAL_MODE_STANDBYMATERIAL_MONETIZATION_ONMATERIAL_MONEYMATERIAL_MONEY_OFFMATERIAL_MONEY_OFF_CSREDMATERIAL_MONITORMATERIAL_MONITOR_HEARTMATERIAL_MONITOR_WEIGHTMATERIAL_MONOCHROME_PHOTOSMATERIAL_MOODMATERIAL_MOOD_BADMATERIAL_MOPEDMATERIAL_MOREMATERIAL_MORE_HORIZMATERIAL_MORE_TIMEMATERIAL_MORE_VERTMATERIAL_MOSQUEMATERIAL_MOTION_PHOTOS_AUTOMATERIAL_MOTION_PHOTOS_OFFMATERIAL_MOTION_PHOTOS_ONMATERIAL_MOTION_PHOTOS_PAUSEMATERIAL_MOTION_PHOTOS_PAUSEDMATERIAL_MOTORCYCLEMATERIAL_MOUSEMATERIAL_MOVE_DOWNMATERIAL_MOVE_TO_INBOXMATERIAL_MOVE_UPMATERIAL_MOVIEMATERIAL_MOVIE_CREATIONMATERIAL_MOVIE_EDITMATERIAL_MOVIE_FILTERMATERIAL_MOVINGMATERIAL_MPMATERIAL_MULTILINE_CHARTMATERIAL_MULTIPLE_STOPMATERIAL_MULTITRACK_AUDIOMATERIAL_MUSEUMMATERIAL_MUSIC_NOTEMATERIAL_MUSIC_OFFMATERIAL_MUSIC_VIDEOMATERIAL_MY_LIBRARY_ADDMATERIAL_MY_LIBRARY_BOOKSMATERIAL_MY_LIBRARY_MUSICMATERIAL_MY_LOCATIONMATERIAL_NATMATERIAL_NATUREMATERIAL_NATURE_PEOPLEMATERIAL_NAVIGATE_BEFOREMATERIAL_NAVIGATE_NEXTMATERIAL_NAVIGATIONMATERIAL_NEARBY_ERRORMATERIAL_NEARBY_OFFMATERIAL_NEAR_MEMATERIAL_NEAR_ME_DISABLEDMATERIAL_NEST_CAM_WIRED_STANDMATERIAL_NETWORK_CELLMATERIAL_NETWORK_CHECKMATERIAL_NETWORK_LOCKEDMATERIAL_NETWORK_PINGMATERIAL_NETWORK_WIFIMATERIAL_NETWORK_WIFI_1_BARMATERIAL_NETWORK_WIFI_2_BARMATERIAL_NETWORK_WIFI_3_BARMATERIAL_NEWSPAPERMATERIAL_NEW_LABELMATERIAL_NEW_RELEASESMATERIAL_NEXT_PLANMATERIAL_NEXT_WEEKMATERIAL_NFCMATERIAL_NIGHTLIFEMATERIAL_NIGHTLIGHTMATERIAL_NIGHTLIGHT_ROUNDMATERIAL_NIGHTS_STAYMATERIAL_NIGHT_SHELTERMATERIAL_NOISE_AWAREMATERIAL_NOISE_CONTROL_OFFMATERIAL_NORDIC_WALKINGMATERIAL_NORTHMATERIAL_NORTH_EASTMATERIAL_NORTH_WESTMATERIAL_NOTEMATERIAL_NOTESMATERIAL_NOTE_ADDMATERIAL_NOTE_ALTMATERIAL_NOTIFICATIONSMATERIAL_NOTIFICATIONS_ACTIVEMATERIAL_NOTIFICATIONS_NONEMATERIAL_NOTIFICATIONS_OFFMATERIAL_NOTIFICATIONS_ONMATERIAL_NOTIFICATIONS_PAUSEDMATERIAL_NOTIFICATION_ADDMATERIAL_NOTIFICATION_IMPORTANTMATERIAL_NOT_ACCESSIBLEMATERIAL_NOT_INTERESTEDMATERIAL_NOT_LISTED_LOCATIONMATERIAL_NOT_STARTEDMATERIAL_NOW_WALLPAPERMATERIAL_NOW_WIDGETSMATERIAL_NO_ACCOUNTSMATERIAL_NO_ADULT_CONTENTMATERIAL_NO_BACKPACKMATERIAL_NO_CELLMATERIAL_NO_CRASHMATERIAL_NO_DRINKSMATERIAL_NO_ENCRYPTIONMATERIAL_NO_ENCRYPTION_GMAILERRORREDMATERIAL_NO_FLASHMATERIAL_NO_FOODMATERIAL_NO_LUGGAGEMATERIAL_NO_MEALSMATERIAL_NO_MEALS_OULINEMATERIAL_NO_MEETING_ROOMMATERIAL_NO_PHOTOGRAPHYMATERIAL_NO_SIMMATERIAL_NO_STROLLERMATERIAL_NO_TRANSFERMATERIAL_NUMBERSMATERIAL_OFFLINE_BOLTMATERIAL_OFFLINE_PINMATERIAL_OFFLINE_SHAREMATERIAL_OIL_BARRELMATERIAL_ONDEMAND_VIDEOMATERIAL_ONLINE_PREDICTIONMATERIAL_ON_DEVICE_TRAININGMATERIAL_OPACITYMATERIAL_OPEN_IN_BROWSERMATERIAL_OPEN_IN_FULLMATERIAL_OPEN_IN_NEWMATERIAL_OPEN_IN_NEW_OFFMATERIAL_OPEN_WITHMATERIAL_OTHER_HOUSESMATERIAL_OUTBONDMATERIAL_OUTBOUNDMATERIAL_OUTBOXMATERIAL_OUTDOOR_GRILLMATERIAL_OUTGOING_MAILMATERIAL_OUTLETMATERIAL_OUTLINED_FLAGMATERIAL_OUTPUTMATERIAL_PADDINGMATERIAL_PAGESMATERIAL_PAGEVIEWMATERIAL_PAIDMATERIAL_PALETTEMATERIAL_PALLETMATERIAL_PANORAMAMATERIAL_PANORAMA_FISHEYEMATERIAL_PANORAMA_FISH_EYEMATERIAL_PANORAMA_HORIZONTALMATERIAL_PANORAMA_HORIZONTAL_SELECTMATERIAL_PANORAMA_PHOTOSPHEREMATERIAL_PANORAMA_PHOTOSPHERE_SELECTMATERIAL_PANORAMA_VERTICALMATERIAL_PANORAMA_VERTICAL_SELECTMATERIAL_PANORAMA_WIDE_ANGLEMATERIAL_PANORAMA_WIDE_ANGLE_SELECTMATERIAL_PAN_TOOLMATERIAL_PAN_TOOL_ALTMATERIAL_PARAGLIDINGMATERIAL_PARKMATERIAL_PARTY_MODEMATERIAL_PASSWORDMATERIAL_PATTERNMATERIAL_PAUSEMATERIAL_PAUSE_CIRCLEMATERIAL_PAUSE_CIRCLE_FILLEDMATERIAL_PAUSE_CIRCLE_OUTLINEMATERIAL_PAUSE_PRESENTATIONMATERIAL_PAYMENTMATERIAL_PAYMENTSMATERIAL_PAYPALMATERIAL_PEDAL_BIKEMATERIAL_PENDINGMATERIAL_PENDING_ACTIONSMATERIAL_PENTAGONMATERIAL_PEOPLEMATERIAL_PEOPLE_ALTMATERIAL_PEOPLE_OUTLINEMATERIAL_PERCENTMATERIAL_PERM_CAMERA_MICMATERIAL_PERM_CONTACT_CALMATERIAL_PERM_CONTACT_CALENDARMATERIAL_PERM_DATA_SETTINGMATERIAL_PERM_DEVICE_INFOMATERIAL_PERM_DEVICE_INFORMATIONMATERIAL_PERM_IDENTITYMATERIAL_PERM_MEDIAMATERIAL_PERM_PHONE_MSGMATERIAL_PERM_SCAN_WIFIMATERIAL_PERSONMATERIAL_PERSONAL_INJURYMATERIAL_PERSONAL_VIDEOMATERIAL_PERSON_2MATERIAL_PERSON_3MATERIAL_PERSON_4MATERIAL_PERSON_ADDMATERIAL_PERSON_ADD_ALTMATERIAL_PERSON_ADD_ALT_1MATERIAL_PERSON_ADD_DISABLEDMATERIAL_PERSON_OFFMATERIAL_PERSON_OUTLINEMATERIAL_PERSON_PINMATERIAL_PERSON_PIN_CIRCLEMATERIAL_PERSON_REMOVEMATERIAL_PERSON_REMOVE_ALT_1MATERIAL_PERSON_SEARCHMATERIAL_PEST_CONTROLMATERIAL_PEST_CONTROL_RODENTMATERIAL_PETSMATERIAL_PHISHINGMATERIAL_PHONEMATERIAL_PHONELINKMATERIAL_PHONELINK_ERASEMATERIAL_PHONELINK_LOCKMATERIAL_PHONELINK_OFFMATERIAL_PHONELINK_RINGMATERIAL_PHONELINK_SETUPMATERIAL_PHONE_ANDROIDMATERIAL_PHONE_BLUETOOTH_SPEAKERMATERIAL_PHONE_CALLBACKMATERIAL_PHONE_DISABLEDMATERIAL_PHONE_ENABLEDMATERIAL_PHONE_FORWARDEDMATERIAL_PHONE_IN_TALKMATERIAL_PHONE_IPHONEMATERIAL_PHONE_LOCKEDMATERIAL_PHONE_MISSEDMATERIAL_PHONE_PAUSEDMATERIAL_PHOTOMATERIAL_PHOTO_ALBUMMATERIAL_PHOTO_CAMERAMATERIAL_PHOTO_CAMERA_BACKMATERIAL_PHOTO_CAMERA_FRONTMATERIAL_PHOTO_FILTERMATERIAL_PHOTO_LIBRARYMATERIAL_PHOTO_SIZE_SELECT_ACTUALMATERIAL_PHOTO_SIZE_SELECT_LARGEMATERIAL_PHOTO_SIZE_SELECT_SMALLMATERIAL_PHPMATERIAL_PIANOMATERIAL_PIANO_OFFMATERIAL_PICTURE_AS_PDFMATERIAL_PICTURE_IN_PICTUREMATERIAL_PICTURE_IN_PICTURE_ALTMATERIAL_PIE_CHARTMATERIAL_PIE_CHART_OUTLINEMATERIAL_PIE_CHART_OUTLINEDMATERIAL_PINMATERIAL_PINCHMATERIAL_PIN_DROPMATERIAL_PIN_ENDMATERIAL_PIN_INVOKEMATERIAL_PIVOT_TABLE_CHARTMATERIAL_PIXMATERIAL_PLACEMATERIAL_PLAGIARISMMATERIAL_PLAYLIST_ADDMATERIAL_PLAYLIST_ADD_CHECKMATERIAL_PLAYLIST_ADD_CHECK_CIRCLEMATERIAL_PLAYLIST_ADD_CIRCLEMATERIAL_PLAYLIST_PLAYMATERIAL_PLAYLIST_REMOVEMATERIAL_PLAY_ARROWMATERIAL_PLAY_CIRCLEMATERIAL_PLAY_CIRCLE_FILLMATERIAL_PLAY_CIRCLE_FILLEDMATERIAL_PLAY_CIRCLE_OUTLINEMATERIAL_PLAY_DISABLEDMATERIAL_PLAY_FOR_WORKMATERIAL_PLAY_LESSONMATERIAL_PLUMBINGMATERIAL_PLUS_ONEMATERIAL_PODCASTSMATERIAL_POINT_OF_SALEMATERIAL_POLICYMATERIAL_POLLMATERIAL_POLYLINEMATERIAL_POLYMERMATERIAL_POOLMATERIAL_PORTABLE_WIFI_OFFMATERIAL_PORTRAITMATERIAL_POST_ADDMATERIAL_POWERMATERIAL_POWER_INPUTMATERIAL_POWER_OFFMATERIAL_POWER_SETTINGS_NEWMATERIAL_PRECISION_MANUFACTURINGMATERIAL_PREGNANT_WOMANMATERIAL_PRESENT_TO_ALLMATERIAL_PREVIEWMATERIAL_PRICE_CHANGEMATERIAL_PRICE_CHECKMATERIAL_PRINTMATERIAL_PRINT_DISABLEDMATERIAL_PRIORITY_HIGHMATERIAL_PRIVACY_TIPMATERIAL_PRIVATE_CONNECTIVITYMATERIAL_PRODUCTION_QUANTITY_LIMITSMATERIAL_PROPANEMATERIAL_PROPANE_TANKMATERIAL_PSYCHOLOGYMATERIAL_PSYCHOLOGY_ALTMATERIAL_PUBLICMATERIAL_PUBLIC_OFFMATERIAL_PUBLISHMATERIAL_PUBLISHED_WITH_CHANGESMATERIAL_PUNCH_CLOCKMATERIAL_PUSH_PINMATERIAL_QR_CODEMATERIAL_QR_CODE_2MATERIAL_QR_CODE_SCANNERMATERIAL_QUERY_BUILDERMATERIAL_QUERY_STATSMATERIAL_QUESTION_ANSWERMATERIAL_QUESTION_MARKMATERIAL_QUEUEMATERIAL_QUEUE_MUSICMATERIAL_QUEUE_PLAY_NEXTMATERIAL_QUICKREPLYMATERIAL_QUICK_CONTACTS_DIALERMATERIAL_QUICK_CONTACTS_MAILMATERIAL_QUIZMATERIAL_QUORAMATERIAL_RADARMATERIAL_RADIOMATERIAL_RADIO_BUTTON_CHECKEDMATERIAL_RADIO_BUTTON_OFFMATERIAL_RADIO_BUTTON_ONMATERIAL_RADIO_BUTTON_UNCHECKEDMATERIAL_RAILWAY_ALERTMATERIAL_RAMEN_DININGMATERIAL_RAMP_LEFTMATERIAL_RAMP_RIGHTMATERIAL_RATE_REVIEWMATERIAL_RAW_OFFMATERIAL_RAW_ONMATERIAL_READ_MOREMATERIAL_REAL_ESTATE_AGENTMATERIAL_REBASE_EDITMATERIAL_RECEIPTMATERIAL_RECEIPT_LONGMATERIAL_RECENT_ACTORSMATERIAL_RECOMMENDMATERIAL_RECORD_VOICE_OVERMATERIAL_RECTANGLEMATERIAL_RECYCLINGMATERIAL_REDDITMATERIAL_REDEEMMATERIAL_REDOMATERIAL_REDUCE_CAPACITYMATERIAL_REFRESHMATERIAL_REMEMBER_MEMATERIAL_REMOVEMATERIAL_REMOVE_CIRCLEMATERIAL_REMOVE_CIRCLE_OUTLINEMATERIAL_REMOVE_DONEMATERIAL_REMOVE_FROM_QUEUEMATERIAL_REMOVE_MODERATORMATERIAL_REMOVE_RED_EYEMATERIAL_REMOVE_ROADMATERIAL_REMOVE_SHOPPING_CARTMATERIAL_REORDERMATERIAL_REPARTITIONMATERIAL_REPEATMATERIAL_REPEAT_ONMATERIAL_REPEAT_ONEMATERIAL_REPEAT_ONE_ONMATERIAL_REPLAYMATERIAL_REPLAY_10MATERIAL_REPLAY_30MATERIAL_REPLAY_5MATERIAL_REPLAY_CIRCLE_FILLEDMATERIAL_REPLYMATERIAL_REPLY_ALLMATERIAL_REPORTMATERIAL_REPORT_GMAILERRORREDMATERIAL_REPORT_OFFMATERIAL_REPORT_PROBLEMMATERIAL_REQUEST_PAGEMATERIAL_REQUEST_QUOTEMATERIAL_RESET_TVMATERIAL_RESTART_ALTMATERIAL_RESTAURANTMATERIAL_RESTAURANT_MENUMATERIAL_RESTOREMATERIAL_RESTORE_FROM_TRASHMATERIAL_RESTORE_PAGEMATERIAL_REVIEWSMATERIAL_RICE_BOWLMATERIAL_RING_VOLUMEMATERIAL_ROCKETMATERIAL_ROCKET_LAUNCHMATERIAL_ROLLER_SHADESMATERIAL_ROLLER_SHADES_CLOSEDMATERIAL_ROLLER_SKATINGMATERIAL_ROOFINGMATERIAL_ROOMMATERIAL_ROOM_PREFERENCESMATERIAL_ROOM_SERVICEMATERIAL_ROTATE_90_DEGREES_CCWMATERIAL_ROTATE_90_DEGREES_CWMATERIAL_ROTATE_LEFTMATERIAL_ROTATE_RIGHTMATERIAL_ROUNDABOUT_LEFTMATERIAL_ROUNDABOUT_RIGHTMATERIAL_ROUNDED_CORNERMATERIAL_ROUTEMATERIAL_ROUTERMATERIAL_ROWINGMATERIAL_RSS_FEEDMATERIAL_RSVPMATERIAL_RTTMATERIAL_RULEMATERIAL_RULE_FOLDERMATERIAL_RUNNING_WITH_ERRORSMATERIAL_RUN_CIRCLEMATERIAL_RV_HOOKUPMATERIAL_R_MOBILEDATAMATERIAL_SAFETY_CHECKMATERIAL_SAFETY_DIVIDERMATERIAL_SAILINGMATERIAL_SANITIZERMATERIAL_SATELLITEMATERIAL_SATELLITE_ALTMATERIAL_SAVEMATERIAL_SAVED_SEARCHMATERIAL_SAVE_ALTMATERIAL_SAVE_ASMATERIAL_SAVINGSMATERIAL_SCALEMATERIAL_SCANNERMATERIAL_SCATTER_PLOTMATERIAL_SCHEDULEMATERIAL_SCHEDULE_SENDMATERIAL_SCHEMAMATERIAL_SCHOOLMATERIAL_SCIENCEMATERIAL_SCOREMATERIAL_SCOREBOARDMATERIAL_SCREENSHOTMATERIAL_SCREENSHOT_MONITORMATERIAL_SCREEN_LOCK_LANDSCAPEMATERIAL_SCREEN_LOCK_PORTRAITMATERIAL_SCREEN_LOCK_ROTATIONMATERIAL_SCREEN_ROTATIONMATERIAL_SCREEN_ROTATION_ALTMATERIAL_SCREEN_SEARCH_DESKTOPMATERIAL_SCREEN_SHAREMATERIAL_SCUBA_DIVINGMATERIAL_SDMATERIAL_SD_CARDMATERIAL_SD_CARD_ALERTMATERIAL_SD_STORAGEMATERIAL_SEARCHMATERIAL_SEARCH_OFFMATERIAL_SECURITYMATERIAL_SECURITY_UPDATEMATERIAL_SECURITY_UPDATE_GOODMATERIAL_SECURITY_UPDATE_WARNINGMATERIAL_SEGMENTMATERIAL_SELECT_ALLMATERIAL_SELF_IMPROVEMENTMATERIAL_SELLMATERIAL_SENDMATERIAL_SEND_AND_ARCHIVEMATERIAL_SEND_TIME_EXTENSIONMATERIAL_SEND_TO_MOBILEMATERIAL_SENSORSMATERIAL_SENSORS_OFFMATERIAL_SENSOR_DOORMATERIAL_SENSOR_OCCUPIEDMATERIAL_SENSOR_WINDOWMATERIAL_SENTIMENT_DISSATISFIEDMATERIAL_SENTIMENT_NEUTRALMATERIAL_SENTIMENT_SATISFIEDMATERIAL_SENTIMENT_SATISFIED_ALTMATERIAL_SENTIMENT_VERY_DISSATISFIEDMATERIAL_SENTIMENT_VERY_SATISFIEDMATERIAL_SETTINGSMATERIAL_SETTINGS_ACCESSIBILITYMATERIAL_SETTINGS_APPLICATIONSMATERIAL_SETTINGS_BACKUP_RESTOREMATERIAL_SETTINGS_BLUETOOTHMATERIAL_SETTINGS_BRIGHTNESSMATERIAL_SETTINGS_CELLMATERIAL_SETTINGS_DISPLAYMATERIAL_SETTINGS_ETHERNETMATERIAL_SETTINGS_INPUT_ANTENNAMATERIAL_SETTINGS_INPUT_COMPONENTMATERIAL_SETTINGS_INPUT_COMPOSITEMATERIAL_SETTINGS_INPUT_HDMIMATERIAL_SETTINGS_INPUT_SVIDEOMATERIAL_SETTINGS_OVERSCANMATERIAL_SETTINGS_PHONEMATERIAL_SETTINGS_POWERMATERIAL_SETTINGS_REMOTEMATERIAL_SETTINGS_SUGGESTMATERIAL_SETTINGS_SYSTEM_DAYDREAMMATERIAL_SETTINGS_VOICEMATERIAL_SET_MEALMATERIAL_SEVERE_COLDMATERIAL_SHAPE_LINEMATERIAL_SHAREMATERIAL_SHARE_ARRIVAL_TIMEMATERIAL_SHARE_LOCATIONMATERIAL_SHELVESMATERIAL_SHIELDMATERIAL_SHIELD_MOONMATERIAL_SHOPMATERIAL_SHOPIFYMATERIAL_SHOPPING_BAGMATERIAL_SHOPPING_BASKETMATERIAL_SHOPPING_CARTMATERIAL_SHOPPING_CART_CHECKOUTMATERIAL_SHOP_2MATERIAL_SHOP_TWOMATERIAL_SHORTCUTMATERIAL_SHORT_TEXTMATERIAL_SHOWERMATERIAL_SHOW_CHARTMATERIAL_SHUFFLEMATERIAL_SHUFFLE_ONMATERIAL_SHUTTER_SPEEDMATERIAL_SICKMATERIAL_SIGNAL_CELLULAR_0_BARMATERIAL_SIGNAL_CELLULAR_4_BARMATERIAL_SIGNAL_CELLULAR_ALTMATERIAL_SIGNAL_CELLULAR_ALT_1_BARMATERIAL_SIGNAL_CELLULAR_ALT_2_BARMATERIAL_SIGNAL_CELLULAR_CONNECTED_NO_INTERNET_0_BARMATERIAL_SIGNAL_CELLULAR_CONNECTED_NO_INTERNET_4_BARMATERIAL_SIGNAL_CELLULAR_NODATAMATERIAL_SIGNAL_CELLULAR_NO_SIMMATERIAL_SIGNAL_CELLULAR_NULLMATERIAL_SIGNAL_CELLULAR_OFFMATERIAL_SIGNAL_WIFI_0_BARMATERIAL_SIGNAL_WIFI_4_BARMATERIAL_SIGNAL_WIFI_4_BAR_LOCKMATERIAL_SIGNAL_WIFI_BADMATERIAL_SIGNAL_WIFI_CONNECTED_NO_INTERNET_4MATERIAL_SIGNAL_WIFI_OFFMATERIAL_SIGNAL_WIFI_STATUSBAR_4_BARMATERIAL_SIGNAL_WIFI_STATUSBAR_CONNECTED_NO_INTERNET_4MATERIAL_SIGNAL_WIFI_STATUSBAR_NULLMATERIAL_SIGNPOSTMATERIAL_SIGN_LANGUAGEMATERIAL_SIM_CARDMATERIAL_SIM_CARD_ALERTMATERIAL_SIM_CARD_DOWNLOADMATERIAL_SINGLE_BEDMATERIAL_SIPMATERIAL_SKATEBOARDINGMATERIAL_SKIP_NEXTMATERIAL_SKIP_PREVIOUSMATERIAL_SLEDDINGMATERIAL_SLIDESHOWMATERIAL_SLOW_MOTION_VIDEOMATERIAL_SMARTPHONEMATERIAL_SMART_BUTTONMATERIAL_SMART_DISPLAYMATERIAL_SMART_SCREENMATERIAL_SMART_TOYMATERIAL_SMOKE_FREEMATERIAL_SMOKING_ROOMSMATERIAL_SMSMATERIAL_SMS_FAILEDMATERIAL_SNAPCHATMATERIAL_SNIPPET_FOLDERMATERIAL_SNOOZEMATERIAL_SNOWBOARDINGMATERIAL_SNOWINGMATERIAL_SNOWMOBILEMATERIAL_SNOWSHOEINGMATERIAL_SOAPMATERIAL_SOCIAL_DISTANCEMATERIAL_SOLAR_POWERMATERIAL_SORTMATERIAL_SORT_BY_ALPHAMATERIAL_SOSMATERIAL_SOUP_KITCHENMATERIAL_SOURCEMATERIAL_SOUTHMATERIAL_SOUTH_AMERICAMATERIAL_SOUTH_EASTMATERIAL_SOUTH_WESTMATERIAL_SPAMATERIAL_SPACE_BARMATERIAL_SPACE_DASHBOARDMATERIAL_SPATIAL_AUDIOMATERIAL_SPATIAL_AUDIO_OFFMATERIAL_SPATIAL_TRACKINGMATERIAL_SPEAKERMATERIAL_SPEAKER_GROUPMATERIAL_SPEAKER_NOTESMATERIAL_SPEAKER_NOTES_OFFMATERIAL_SPEAKER_PHONEMATERIAL_SPEEDMATERIAL_SPELLCHECKMATERIAL_SPLITSCREENMATERIAL_SPOKEMATERIAL_SPORTSMATERIAL_SPORTS_BARMATERIAL_SPORTS_BASEBALLMATERIAL_SPORTS_BASKETBALLMATERIAL_SPORTS_CRICKETMATERIAL_SPORTS_ESPORTSMATERIAL_SPORTS_FOOTBALLMATERIAL_SPORTS_GOLFMATERIAL_SPORTS_GYMNASTICSMATERIAL_SPORTS_HANDBALLMATERIAL_SPORTS_HOCKEYMATERIAL_SPORTS_KABADDIMATERIAL_SPORTS_MARTIAL_ARTSMATERIAL_SPORTS_MMAMATERIAL_SPORTS_MOTORSPORTSMATERIAL_SPORTS_RUGBYMATERIAL_SPORTS_SCOREMATERIAL_SPORTS_SOCCERMATERIAL_SPORTS_TENNISMATERIAL_SPORTS_VOLLEYBALLMATERIAL_SQUAREMATERIAL_SQUARE_FOOTMATERIAL_SSID_CHARTMATERIAL_STACKED_BAR_CHARTMATERIAL_STACKED_LINE_CHARTMATERIAL_STADIUMMATERIAL_STAIRSMATERIAL_STARMATERIAL_STARSMATERIAL_STARTMATERIAL_STAR_BORDERMATERIAL_STAR_BORDER_PURPLE500MATERIAL_STAR_HALFMATERIAL_STAR_OUTLINEMATERIAL_STAR_PURPLE500MATERIAL_STAR_RATEMATERIAL_STAY_CURRENT_LANDSCAPEMATERIAL_STAY_CURRENT_PORTRAITMATERIAL_STAY_PRIMARY_LANDSCAPEMATERIAL_STAY_PRIMARY_PORTRAITMATERIAL_STICKY_NOTE_2MATERIAL_STOPMATERIAL_STOP_CIRCLEMATERIAL_STOP_SCREEN_SHAREMATERIAL_STORAGEMATERIAL_STOREMATERIAL_STOREFRONTMATERIAL_STORE_MALL_DIRECTORYMATERIAL_STORMMATERIAL_STRAIGHTMATERIAL_STRAIGHTENMATERIAL_STREAMMATERIAL_STREETVIEWMATERIAL_STRIKETHROUGH_SMATERIAL_STROLLERMATERIAL_STYLEMATERIAL_SUBDIRECTORY_ARROW_LEFTMATERIAL_SUBDIRECTORY_ARROW_RIGHTMATERIAL_SUBJECTMATERIAL_SUBSCRIPTMATERIAL_SUBSCRIPTIONSMATERIAL_SUBTITLESMATERIAL_SUBTITLES_OFFMATERIAL_SUBWAYMATERIAL_SUMMARIZEMATERIAL_SUNNYMATERIAL_SUNNY_SNOWINGMATERIAL_SUPERSCRIPTMATERIAL_SUPERVISED_USER_CIRCLEMATERIAL_SUPERVISOR_ACCOUNTMATERIAL_SUPPORTMATERIAL_SUPPORT_AGENTMATERIAL_SURFINGMATERIAL_SURROUND_SOUNDMATERIAL_SWAP_CALLSMATERIAL_SWAP_HORIZMATERIAL_SWAP_HORIZONTAL_CIRCLEMATERIAL_SWAP_VERTMATERIAL_SWAP_VERTICAL_CIRCLEMATERIAL_SWAP_VERT_CIRCLEMATERIAL_SWIPEMATERIAL_SWIPE_DOWNMATERIAL_SWIPE_DOWN_ALTMATERIAL_SWIPE_LEFTMATERIAL_SWIPE_LEFT_ALTMATERIAL_SWIPE_RIGHTMATERIAL_SWIPE_RIGHT_ALTMATERIAL_SWIPE_UPMATERIAL_SWIPE_UP_ALTMATERIAL_SWIPE_VERTICALMATERIAL_SWITCH_ACCESS_SHORTCUTMATERIAL_SWITCH_ACCESS_SHORTCUT_ADDMATERIAL_SWITCH_ACCOUNTMATERIAL_SWITCH_CAMERAMATERIAL_SWITCH_LEFTMATERIAL_SWITCH_RIGHTMATERIAL_SWITCH_VIDEOMATERIAL_SYNAGOGUEMATERIAL_SYNCMATERIAL_SYNC_ALTMATERIAL_SYNC_DISABLEDMATERIAL_SYNC_LOCKMATERIAL_SYNC_PROBLEMMATERIAL_SYSTEM_SECURITY_UPDATEMATERIAL_SYSTEM_SECURITY_UPDATE_GOODMATERIAL_SYSTEM_SECURITY_UPDATE_WARNINGMATERIAL_SYSTEM_UPDATEMATERIAL_SYSTEM_UPDATE_ALTMATERIAL_SYSTEM_UPDATE_TVMATERIAL_TABMATERIAL_TABLETMATERIAL_TABLET_ANDROIDMATERIAL_TABLET_MACMATERIAL_TABLE_BARMATERIAL_TABLE_CHARTMATERIAL_TABLE_RESTAURANTMATERIAL_TABLE_ROWSMATERIAL_TABLE_VIEWMATERIAL_TAB_UNSELECTEDMATERIAL_TAGMATERIAL_TAG_FACESMATERIAL_TAKEOUT_DININGMATERIAL_TAPASMATERIAL_TAP_AND_PLAYMATERIAL_TASKMATERIAL_TASK_ALTMATERIAL_TAXI_ALERTMATERIAL_TELEGRAMMATERIAL_TEMPLE_BUDDHISTMATERIAL_TEMPLE_HINDUMATERIAL_TERMINALMATERIAL_TERRAINMATERIAL_TEXTSMSMATERIAL_TEXTUREMATERIAL_TEXT_DECREASEMATERIAL_TEXT_FIELDSMATERIAL_TEXT_FORMATMATERIAL_TEXT_INCREASEMATERIAL_TEXT_ROTATE_UPMATERIAL_TEXT_ROTATE_VERTICALMATERIAL_TEXT_ROTATION_ANGLEDOWNMATERIAL_TEXT_ROTATION_ANGLEUPMATERIAL_TEXT_ROTATION_DOWNMATERIAL_TEXT_ROTATION_NONEMATERIAL_TEXT_SNIPPETMATERIAL_THEATERSMATERIAL_THEATER_COMEDYMATERIAL_THERMOSTATMATERIAL_THERMOSTAT_AUTOMATERIAL_THUMBS_UP_DOWNMATERIAL_THUMB_DOWNMATERIAL_THUMB_DOWN_ALTMATERIAL_THUMB_DOWN_OFF_ALTMATERIAL_THUMB_UPMATERIAL_THUMB_UP_ALTMATERIAL_THUMB_UP_OFF_ALTMATERIAL_THUNDERSTORMMATERIAL_TIKTOKMATERIAL_TIMELAPSEMATERIAL_TIMELINEMATERIAL_TIMERMATERIAL_TIMER_10MATERIAL_TIMER_10_SELECTMATERIAL_TIMER_3MATERIAL_TIMER_3_SELECTMATERIAL_TIMER_OFFMATERIAL_TIME_TO_LEAVEMATERIAL_TIPS_AND_UPDATESMATERIAL_TIRE_REPAIRMATERIAL_TITLEMATERIAL_TOCMATERIAL_TODAYMATERIAL_TOGGLE_OFFMATERIAL_TOGGLE_ONMATERIAL_TOKENMATERIAL_TOLLMATERIAL_TONALITYMATERIAL_TOPICMATERIAL_TORNADOMATERIAL_TOUCH_APPMATERIAL_TOURMATERIAL_TOYSMATERIAL_TRACK_CHANGESMATERIAL_TRAFFICMATERIAL_TRAINMATERIAL_TRAMMATERIAL_TRANSCRIBEMATERIAL_TRANSFER_WITHIN_A_STATIONMATERIAL_TRANSFORMMATERIAL_TRANSGENDERMATERIAL_TRANSIT_ENTEREXITMATERIAL_TRANSLATEMATERIAL_TRAVEL_EXPLOREMATERIAL_TRENDING_DOWNMATERIAL_TRENDING_FLATMATERIAL_TRENDING_NEUTRALMATERIAL_TRENDING_UPMATERIAL_TRIP_ORIGINMATERIAL_TROLLEYMATERIAL_TROUBLESHOOTMATERIAL_TRYMATERIAL_TSUNAMIMATERIAL_TTYMATERIAL_TUNEMATERIAL_TUNGSTENMATERIAL_TURNED_INMATERIAL_TURNED_IN_NOTMATERIAL_TURN_LEFTMATERIAL_TURN_RIGHTMATERIAL_TURN_SHARP_LEFTMATERIAL_TURN_SHARP_RIGHTMATERIAL_TURN_SLIGHT_LEFTMATERIAL_TURN_SLIGHT_RIGHTMATERIAL_TVMATERIAL_TV_OFFMATERIAL_TWO_WHEELERMATERIAL_TYPE_SPECIMENMATERIAL_UMBRELLAMATERIAL_UNARCHIVEMATERIAL_UNDOMATERIAL_UNFOLD_LESSMATERIAL_UNFOLD_LESS_DOUBLEMATERIAL_UNFOLD_MOREMATERIAL_UNFOLD_MORE_DOUBLEMATERIAL_UNPUBLISHEDMATERIAL_UNSUBSCRIBEMATERIAL_UPCOMINGMATERIAL_UPDATEMATERIAL_UPDATE_DISABLEDMATERIAL_UPGRADEMATERIAL_UPLOADMATERIAL_UPLOAD_FILEMATERIAL_USBMATERIAL_USB_OFFMATERIAL_U_TURN_LEFTMATERIAL_U_TURN_RIGHTMATERIAL_VACCINESMATERIAL_VAPE_FREEMATERIAL_VAPING_ROOMSMATERIAL_VERIFIEDMATERIAL_VERIFIED_USERMATERIAL_VERTICAL_ALIGN_BOTTOMMATERIAL_VERTICAL_ALIGN_CENTERMATERIAL_VERTICAL_ALIGN_TOPMATERIAL_VERTICAL_DISTRIBUTEMATERIAL_VERTICAL_SHADESMATERIAL_VERTICAL_SHADES_CLOSEDMATERIAL_VERTICAL_SPLITMATERIAL_VIBRATIONMATERIAL_VIDEOCAMMATERIAL_VIDEOCAM_OFFMATERIAL_VIDEOGAME_ASSETMATERIAL_VIDEOGAME_ASSET_OFFMATERIAL_VIDEO_CALLMATERIAL_VIDEO_CAMERA_BACKMATERIAL_VIDEO_CAMERA_FRONTMATERIAL_VIDEO_CHATMATERIAL_VIDEO_COLLECTIONMATERIAL_VIDEO_FILEMATERIAL_VIDEO_LABELMATERIAL_VIDEO_LIBRARYMATERIAL_VIDEO_SETTINGSMATERIAL_VIDEO_STABLEMATERIAL_VIEW_AGENDAMATERIAL_VIEW_ARRAYMATERIAL_VIEW_CAROUSELMATERIAL_VIEW_COLUMNMATERIAL_VIEW_COMFORTABLEMATERIAL_VIEW_COMFYMATERIAL_VIEW_COMFY_ALTMATERIAL_VIEW_COMPACTMATERIAL_VIEW_COMPACT_ALTMATERIAL_VIEW_COZYMATERIAL_VIEW_DAYMATERIAL_VIEW_HEADLINEMATERIAL_VIEW_IN_ARMATERIAL_VIEW_KANBANMATERIAL_VIEW_LISTMATERIAL_VIEW_MODULEMATERIAL_VIEW_QUILTMATERIAL_VIEW_SIDEBARMATERIAL_VIEW_STREAMMATERIAL_VIEW_TIMELINEMATERIAL_VIEW_WEEKMATERIAL_VIGNETTEMATERIAL_VILLAMATERIAL_VISIBILITYMATERIAL_VISIBILITY_OFFMATERIAL_VOICEMAILMATERIAL_VOICE_CHATMATERIAL_VOICE_OVER_OFFMATERIAL_VOLCANOMATERIAL_VOLUME_DOWNMATERIAL_VOLUME_DOWN_ALTMATERIAL_VOLUME_MUTEMATERIAL_VOLUME_OFFMATERIAL_VOLUME_UPMATERIAL_VOLUNTEER_ACTIVISMMATERIAL_VPN_KEYMATERIAL_VPN_KEY_OFFMATERIAL_VPN_LOCKMATERIAL_VRPANOMATERIAL_WALLETMATERIAL_WALLET_GIFTCARDMATERIAL_WALLET_MEMBERSHIPMATERIAL_WALLET_TRAVELMATERIAL_WALLPAPERMATERIAL_WAREHOUSEMATERIAL_WARNINGMATERIAL_WARNING_AMBERMATERIAL_WASHMATERIAL_WATCHMATERIAL_WATCH_LATERMATERIAL_WATCH_OFFMATERIAL_WATERMATERIAL_WATERFALL_CHARTMATERIAL_WATER_DAMAGEMATERIAL_WATER_DROPMATERIAL_WAVESMATERIAL_WAVING_HANDMATERIAL_WB_AUTOMATERIAL_WB_CLOUDYMATERIAL_WB_INCANDESCENTMATERIAL_WB_IRIDESCENTMATERIAL_WB_SHADEMATERIAL_WB_SUNNYMATERIAL_WB_TWIGHLIGHTMATERIAL_WB_TWILIGHTMATERIAL_WCMATERIAL_WEBMATERIAL_WEBHOOKMATERIAL_WEB_ASSETMATERIAL_WEB_ASSET_OFFMATERIAL_WEB_STORIESMATERIAL_WECHATMATERIAL_WEEKENDMATERIAL_WESTMATERIAL_WHATSHOTMATERIAL_WHEELCHAIR_PICKUPMATERIAL_WHERE_TO_VOTEMATERIAL_WIDGETSMATERIAL_WIDTH_FULLMATERIAL_WIDTH_NORMALMATERIAL_WIDTH_WIDEMATERIAL_WIFIMATERIAL_WIFI_1_BARMATERIAL_WIFI_2_BARMATERIAL_WIFI_CALLINGMATERIAL_WIFI_CALLING_3MATERIAL_WIFI_CHANNELMATERIAL_WIFI_FINDMATERIAL_WIFI_LOCKMATERIAL_WIFI_OFFMATERIAL_WIFI_PASSWORDMATERIAL_WIFI_PROTECTED_SETUPMATERIAL_WIFI_TETHERINGMATERIAL_WIFI_TETHERING_ERRORMATERIAL_WIFI_TETHERING_ERROR_ROUNDEDMATERIAL_WIFI_TETHERING_OFFMATERIAL_WINDOWMATERIAL_WIND_POWERMATERIAL_WINE_BARMATERIAL_WOMANMATERIAL_WOMAN_2MATERIAL_WOO_COMMERCEMATERIAL_WORDPRESSMATERIAL_WORKMATERIAL_WORKSPACESMATERIAL_WORKSPACES_FILLEDMATERIAL_WORKSPACES_OUTLINEMATERIAL_WORKSPACE_PREMIUMMATERIAL_WORK_HISTORYMATERIAL_WORK_OFFMATERIAL_WORK_OUTLINEMATERIAL_WRAP_TEXTMATERIAL_WRONG_LOCATIONMATERIAL_WYSIWYGMATERIAL_YARDMATERIAL_YOUTUBE_SEARCHED_FORMATERIAL_ZOOM_INMATERIAL_ZOOM_IN_MAPMATERIAL_ZOOM_OUTMATERIAL_ZOOM_OUT_MAP")); index.put("com.codename1.ui.Form", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); @@ -5445,9 +5776,6 @@ private static void fillFieldIndex20(Map index) { index.put("com.codename1.ui.RichTextFormat", splitMembers("ASCIIDOCHTMLMARKDOWNPLAIN_TEXTRTF")); index.put("com.codename1.ui.SelectableIconHolder", splitMembers("")); index.put("com.codename1.ui.Sheet", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); - } - - private static void fillFieldIndex21(Map index) { index.put("com.codename1.ui.SideMenuBar", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCOMMAND_ACTIONABLECOMMAND_PLACEMENT_KEYCOMMAND_PLACEMENT_VALUE_RIGHTCOMMAND_PLACEMENT_VALUE_TOPCOMMAND_SIDE_COMPONENTCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); index.put("com.codename1.ui.Slider", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); index.put("com.codename1.ui.Stroke", splitMembers("CAP_BUTTCAP_ROUNDCAP_SQUAREJOIN_BEVELJOIN_MITERJOIN_ROUND")); @@ -5474,6 +5802,9 @@ private static void fillFieldIndex21(Map index) { index.put("com.codename1.ui.UIFragment.DefaultComponentFactory", splitMembers("")); index.put("com.codename1.ui.URLImage", splitMembers("FLAG_RESIZE_FAILFLAG_RESIZE_SCALEFLAG_RESIZE_SCALE_TO_FILLRESIZE_FAILRESIZE_SCALERESIZE_SCALE_TO_FILL")); index.put("com.codename1.ui.URLImage.ErrorCallback", splitMembers("")); + } + + private static void fillFieldIndex23(Map index) { index.put("com.codename1.ui.URLImage.ImageAdapter", splitMembers("")); index.put("com.codename1.ui.URLImage.RequestDecorator", splitMembers("")); index.put("com.codename1.ui.VirtualInputDevice", splitMembers("")); @@ -5512,9 +5843,6 @@ private static void fillFieldIndex21(Map index) { index.put("com.codename1.ui.css.CSSThemeCompiler.CSSSyntaxException", splitMembers("")); index.put("com.codename1.ui.editor.CodePureEditor", splitMembers("")); index.put("com.codename1.ui.editor.CodeView", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORKEY_BACKSPACEKEY_COPYKEY_CUTKEY_DELETEKEY_DOWNKEY_ENDKEY_ESCAPEKEY_HOMEKEY_LEFTKEY_PAGE_DOWNKEY_PAGE_UPKEY_PASTEKEY_REDOKEY_RIGHTKEY_SELECT_ALLKEY_TABKEY_UNDOKEY_UPLEFTMOD_ALTMOD_CTRLMOD_SHIFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); - } - - private static void fillFieldIndex22(Map index) { index.put("com.codename1.ui.editor.EditorDocument", splitMembers("")); index.put("com.codename1.ui.editor.EditorHost", splitMembers("")); index.put("com.codename1.ui.editor.EditorView", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORKEY_BACKSPACEKEY_COPYKEY_CUTKEY_DELETEKEY_DOWNKEY_ENDKEY_ESCAPEKEY_HOMEKEY_LEFTKEY_PAGE_DOWNKEY_PAGE_UPKEY_PASTEKEY_REDOKEY_RIGHTKEY_SELECT_ALLKEY_TABKEY_UNDOKEY_UPLEFTMOD_ALTMOD_CTRLMOD_SHIFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); @@ -5541,6 +5869,9 @@ private static void fillFieldIndex22(Map index) { index.put("com.codename1.ui.editor.Tokenizer", splitMembers("COMMENTKEYWORDNUMBERPROPERTYSTATE_BLOCK_COMMENTSTATE_CSS_COMMENT_DECLARATIONSTATE_CSS_DECLARATIONSTATE_NORMALSTATE_TEMPLATESTATE_TRIPLE_DOUBLESTATE_TRIPLE_SINGLESTATE_XML_COMMENTSTRING")); index.put("com.codename1.ui.editor.UndoManager", splitMembers("")); index.put("com.codename1.ui.events.ActionEvent", splitMembers("")); + } + + private static void fillFieldIndex24(Map index) { index.put("com.codename1.ui.events.ActionEvent.Type", splitMembers("CalendarChangeCommandDataDoneDragFinishedEditExceptionIsGalleryTypeSupportedJavaScriptKeyPressKeyReleaseLogLongPointerPressOpenGalleryOrientationChangeOtherPointerPointerDragPointerPressedPointerReleasedPointerWheelPostureChangeProgressResponseShowSizeChangeSwipeTheme")); index.put("com.codename1.ui.events.ActionListener", splitMembers("")); index.put("com.codename1.ui.events.ActionSource", splitMembers("")); @@ -5579,9 +5910,6 @@ private static void fillFieldIndex22(Map index) { index.put("com.codename1.ui.html.HTMLParser", splitMembers("")); index.put("com.codename1.ui.html.HTMLUtils", splitMembers("")); index.put("com.codename1.ui.html.IOCallback", splitMembers("")); - } - - private static void fillFieldIndex23(Map index) { index.put("com.codename1.ui.layouts.BorderLayout", splitMembers("CENTERCENTER_BEHAVIOR_CENTERCENTER_BEHAVIOR_CENTER_ABSOLUTECENTER_BEHAVIOR_SCALECENTER_BEHAVIOR_TOTAL_BELLOWCENTER_BEHAVIOR_TOTAL_BELOWEASTNORTHOVERLAYSOUTHWEST")); index.put("com.codename1.ui.layouts.BoxLayout", splitMembers("X_AXISX_AXIS_NO_GROWY_AXISY_AXIS_BOTTOM_LAST")); index.put("com.codename1.ui.layouts.CoordinateLayout", splitMembers("")); @@ -5608,6 +5936,9 @@ private static void fillFieldIndex23(Map index) { index.put("com.codename1.ui.layouts.mig.LayoutCallback", splitMembers("")); index.put("com.codename1.ui.layouts.mig.LayoutUtil", splitMembers("HAS_BEANSHORIZONTALINFMAXMINPREFVERTICAL")); index.put("com.codename1.ui.layouts.mig.LinkHandler", splitMembers("HEIGHTWIDTHXX2YY2")); + } + + private static void fillFieldIndex25(Map index) { index.put("com.codename1.ui.layouts.mig.MigLayout", splitMembers("")); index.put("com.codename1.ui.layouts.mig.PlatformDefaults", splitMembers("BASE_FONT_SIZEBASE_REAL_PIXELBASE_SCALE_FACTORGNOMEMAC_OSXVISUAL_PADDING_PROPERTYWINDOWS_XP")); index.put("com.codename1.ui.layouts.mig.UnitConverter", splitMembers("UNABLE")); @@ -5646,9 +5977,6 @@ private static void fillFieldIndex23(Map index) { index.put("com.codename1.ui.plaf.StyleParser.StyleInfo", splitMembers("")); index.put("com.codename1.ui.plaf.UIManager", splitMembers("")); index.put("com.codename1.ui.scene.Bounds", splitMembers("")); - } - - private static void fillFieldIndex24(Map index) { index.put("com.codename1.ui.scene.Camera", splitMembers("farClipnearClip")); index.put("com.codename1.ui.scene.Node", splitMembers("boundsInLocallayoutXlayoutYlayoutZlocalCanvasZopacitypaintingRectrotaterotationAxisscaleXscaleYscaleZtranslateXtranslateYtranslateZvisible")); index.put("com.codename1.ui.scene.NodePainter", splitMembers("")); @@ -5675,6 +6003,9 @@ private static void fillFieldIndex24(Map index) { index.put("com.codename1.ui.tree.Tree", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); index.put("com.codename1.ui.tree.Tree.TreeState", splitMembers("")); index.put("com.codename1.ui.tree.TreeModel", splitMembers("")); + } + + private static void fillFieldIndex26(Map index) { index.put("com.codename1.ui.util.Effects", splitMembers("")); index.put("com.codename1.ui.util.EmbeddedContainer", splitMembers("BASELINEBOTTOMBRB_CENTER_OFFSETBRB_CONSTANT_ASCENTBRB_CONSTANT_DESCENTBRB_OTHERCENTERCROSSHAIR_CURSORDEFAULT_CURSORDRAG_REGION_IMMEDIATELY_DRAG_XDRAG_REGION_IMMEDIATELY_DRAG_XYDRAG_REGION_IMMEDIATELY_DRAG_YDRAG_REGION_LIKELY_DRAG_XDRAG_REGION_LIKELY_DRAG_XYDRAG_REGION_LIKELY_DRAG_YDRAG_REGION_NOT_DRAGGABLEDRAG_REGION_POSSIBLE_DRAG_XDRAG_REGION_POSSIBLE_DRAG_XYDRAG_REGION_POSSIBLE_DRAG_YE_RESIZE_CURSORHAND_CURSORLEFTMOVE_CURSORNE_RESIZE_CURSORNW_RESIZE_CURSORN_RESIZE_CURSORRIGHTSE_RESIZE_CURSORSW_RESIZE_CURSORS_RESIZE_CURSORTEXT_CURSORTOPWAIT_CURSORW_RESIZE_CURSOR")); index.put("com.codename1.ui.util.EventDispatcher", splitMembers("")); @@ -5713,9 +6044,6 @@ private static void fillFieldIndex24(Map index) { index.put("com.codename1.util.EasyThread.ErrorListener", splitMembers("")); index.put("com.codename1.util.FailureCallback", splitMembers("")); index.put("com.codename1.util.LazyValue", splitMembers("")); - } - - private static void fillFieldIndex25(Map index) { index.put("com.codename1.util.MathUtil", splitMembers("")); index.put("com.codename1.util.OnComplete", splitMembers("")); index.put("com.codename1.util.RunnableWithResult", splitMembers("")); @@ -5742,6 +6070,9 @@ private static void fillFieldIndex25(Map index) { index.put("com.codename1.util.regex.StringReader", splitMembers("")); index.put("com.codename1.vr.HeadTracker", splitMembers("")); index.put("com.codename1.vr.Media360View", splitMembers("")); + } + + private static void fillFieldIndex27(Map index) { index.put("com.codename1.vr.OrientationFilter", splitMembers("")); index.put("com.codename1.vr.TextureSource", splitMembers("")); index.put("com.codename1.vr.VRCameraRig", splitMembers("")); @@ -5750,6 +6081,7 @@ private static void fillFieldIndex25(Map index) { index.put("com.codename1.vr.VRSettings", splitMembers("")); index.put("com.codename1.vr.VRView", splitMembers("")); index.put("com.codename1.wearable.WearableConnection", splitMembers("")); + index.put("com.codename1.wearable.WearableConnection.DroppedDeliveryHandler", splitMembers("")); index.put("com.codename1.wearable.WearableDataListener", splitMembers("")); index.put("com.codename1.wearable.WearableMessage", splitMembers("")); index.put("com.codename1.wearable.WearableMessageListener", splitMembers("")); @@ -5780,9 +6112,6 @@ private static void fillFieldIndex25(Map index) { index.put("java.io.FileNotFoundException", splitMembers("")); index.put("java.io.Flushable", splitMembers("")); index.put("java.io.IOException", splitMembers("")); - } - - private static void fillFieldIndex26(Map index) { index.put("java.io.InputStream", splitMembers("")); index.put("java.io.InputStreamReader", splitMembers("")); index.put("java.io.InterruptedIOException", splitMembers("")); @@ -5808,6 +6137,9 @@ private static void fillFieldIndex26(Map index) { index.put("java.lang.Character", splitMembers("")); index.put("java.lang.Class", splitMembers("")); index.put("java.lang.ClassCastException", splitMembers("")); + } + + private static void fillFieldIndex28(Map index) { index.put("java.lang.ClassLoader", splitMembers("")); index.put("java.lang.ClassNotFoundException", splitMembers("")); index.put("java.lang.CloneNotSupportedException", splitMembers("")); @@ -5847,9 +6179,6 @@ private static void fillFieldIndex26(Map index) { index.put("java.lang.SafeVarargs", splitMembers("")); index.put("java.lang.SecurityException", splitMembers("")); index.put("java.lang.Short", splitMembers("")); - } - - private static void fillFieldIndex27(Map index) { index.put("java.lang.StackTraceElement", splitMembers("")); index.put("java.lang.String", splitMembers("")); index.put("java.lang.StringBuffer", splitMembers("")); @@ -5875,6 +6204,9 @@ private static void fillFieldIndex27(Map index) { index.put("java.text.DateFormat", splitMembers("")); index.put("java.text.DateFormatSymbols", splitMembers("")); index.put("java.text.Format", splitMembers("")); + } + + private static void fillFieldIndex29(Map index) { index.put("java.text.ParseException", splitMembers("")); index.put("java.text.SimpleDateFormat", splitMembers("")); index.put("java.time.Clock", splitMembers("")); @@ -5914,9 +6246,6 @@ private static void fillFieldIndex27(Map index) { index.put("java.util.Dictionary", splitMembers("")); index.put("java.util.EmptyStackException", splitMembers("")); index.put("java.util.Enumeration", splitMembers("")); - } - - private static void fillFieldIndex28(Map index) { index.put("java.util.EventListener", splitMembers("")); index.put("java.util.HashMap", splitMembers("")); index.put("java.util.HashSet", splitMembers("")); @@ -5942,6 +6271,9 @@ private static void fillFieldIndex28(Map index) { index.put("java.util.Random", splitMembers("")); index.put("java.util.RandomAccess", splitMembers("")); index.put("java.util.Set", splitMembers("")); + } + + private static void fillFieldIndex30(Map index) { index.put("java.util.SortedMap", splitMembers("")); index.put("java.util.SortedSet", splitMembers("")); index.put("java.util.Stack", splitMembers("")); @@ -6020,6 +6352,9 @@ private static Class findClassInPackage(String packageName, String fullName) if ("com.codename1.annotations".equals(packageName)) { return GeneratedAccess_com_codename1_annotations.findClass(fullName); } + if ("com.codename1.annotations.buildhints".equals(packageName)) { + return GeneratedAccess_com_codename1_annotations_buildhints.findClass(fullName); + } if ("com.codename1.annotations.graphql".equals(packageName)) { return GeneratedAccess_com_codename1_annotations_graphql.findClass(fullName); } @@ -6179,6 +6514,21 @@ private static Class findClassInPackage(String packageName, String fullName) if ("com.codename1.health.workout".equals(packageName)) { return GeneratedAccess_com_codename1_health_workout.findClass(fullName); } + if ("com.codename1.home".equals(packageName)) { + return GeneratedAccess_com_codename1_home.findClass(fullName); + } + if ("com.codename1.home.commissioning".equals(packageName)) { + return GeneratedAccess_com_codename1_home_commissioning.findClass(fullName); + } + if ("com.codename1.home.spi".equals(packageName)) { + return GeneratedAccess_com_codename1_home_spi.findClass(fullName); + } + if ("com.codename1.intents".equals(packageName)) { + return GeneratedAccess_com_codename1_intents.findClass(fullName); + } + if ("com.codename1.intents.spi".equals(packageName)) { + return GeneratedAccess_com_codename1_intents_spi.findClass(fullName); + } if ("com.codename1.io".equals(packageName)) { return GeneratedAccess_com_codename1_io.findClass(fullName); } @@ -6290,6 +6640,9 @@ private static Class findClassInPackage(String packageName, String fullName) if ("com.codename1.security".equals(packageName)) { return GeneratedAccess_com_codename1_security.findClass(fullName); } + if ("com.codename1.security.hardening".equals(packageName)) { + return GeneratedAccess_com_codename1_security_hardening.findClass(fullName); + } if ("com.codename1.security.shield".equals(packageName)) { return GeneratedAccess_com_codename1_security_shield.findClass(fullName); } @@ -6486,6 +6839,9 @@ public Object construct(Class type, Object[] args) throws Exception { if ("com.codename1.annotations".equals(candidate)) { return GeneratedAccess_com_codename1_annotations.construct(type, args); } + if ("com.codename1.annotations.buildhints".equals(candidate)) { + return GeneratedAccess_com_codename1_annotations_buildhints.construct(type, args); + } if ("com.codename1.annotations.graphql".equals(candidate)) { return GeneratedAccess_com_codename1_annotations_graphql.construct(type, args); } @@ -6645,6 +7001,21 @@ public Object construct(Class type, Object[] args) throws Exception { if ("com.codename1.health.workout".equals(candidate)) { return GeneratedAccess_com_codename1_health_workout.construct(type, args); } + if ("com.codename1.home".equals(candidate)) { + return GeneratedAccess_com_codename1_home.construct(type, args); + } + if ("com.codename1.home.commissioning".equals(candidate)) { + return GeneratedAccess_com_codename1_home_commissioning.construct(type, args); + } + if ("com.codename1.home.spi".equals(candidate)) { + return GeneratedAccess_com_codename1_home_spi.construct(type, args); + } + if ("com.codename1.intents".equals(candidate)) { + return GeneratedAccess_com_codename1_intents.construct(type, args); + } + if ("com.codename1.intents.spi".equals(candidate)) { + return GeneratedAccess_com_codename1_intents_spi.construct(type, args); + } if ("com.codename1.io".equals(candidate)) { return GeneratedAccess_com_codename1_io.construct(type, args); } @@ -6756,6 +7127,9 @@ public Object construct(Class type, Object[] args) throws Exception { if ("com.codename1.security".equals(candidate)) { return GeneratedAccess_com_codename1_security.construct(type, args); } + if ("com.codename1.security.hardening".equals(candidate)) { + return GeneratedAccess_com_codename1_security_hardening.construct(type, args); + } if ("com.codename1.security.shield".equals(candidate)) { return GeneratedAccess_com_codename1_security_shield.construct(type, args); } @@ -6943,6 +7317,9 @@ public Object invokeStatic(Class type, String name, Object[] args) throws Exc if ("com.codename1.annotations".equals(candidate)) { return GeneratedAccess_com_codename1_annotations.invokeStatic(type, name, args); } + if ("com.codename1.annotations.buildhints".equals(candidate)) { + return GeneratedAccess_com_codename1_annotations_buildhints.invokeStatic(type, name, args); + } if ("com.codename1.annotations.graphql".equals(candidate)) { return GeneratedAccess_com_codename1_annotations_graphql.invokeStatic(type, name, args); } @@ -7102,6 +7479,21 @@ public Object invokeStatic(Class type, String name, Object[] args) throws Exc if ("com.codename1.health.workout".equals(candidate)) { return GeneratedAccess_com_codename1_health_workout.invokeStatic(type, name, args); } + if ("com.codename1.home".equals(candidate)) { + return GeneratedAccess_com_codename1_home.invokeStatic(type, name, args); + } + if ("com.codename1.home.commissioning".equals(candidate)) { + return GeneratedAccess_com_codename1_home_commissioning.invokeStatic(type, name, args); + } + if ("com.codename1.home.spi".equals(candidate)) { + return GeneratedAccess_com_codename1_home_spi.invokeStatic(type, name, args); + } + if ("com.codename1.intents".equals(candidate)) { + return GeneratedAccess_com_codename1_intents.invokeStatic(type, name, args); + } + if ("com.codename1.intents.spi".equals(candidate)) { + return GeneratedAccess_com_codename1_intents_spi.invokeStatic(type, name, args); + } if ("com.codename1.io".equals(candidate)) { return GeneratedAccess_com_codename1_io.invokeStatic(type, name, args); } @@ -7213,6 +7605,9 @@ public Object invokeStatic(Class type, String name, Object[] args) throws Exc if ("com.codename1.security".equals(candidate)) { return GeneratedAccess_com_codename1_security.invokeStatic(type, name, args); } + if ("com.codename1.security.hardening".equals(candidate)) { + return GeneratedAccess_com_codename1_security_hardening.invokeStatic(type, name, args); + } if ("com.codename1.security.shield".equals(candidate)) { return GeneratedAccess_com_codename1_security_shield.invokeStatic(type, name, args); } @@ -7386,151 +7781,158 @@ private static java.util.Map buildPackageHandlerIndex() { m.put("com.codename1.ai.vision", Integer.valueOf(5)); m.put("com.codename1.analytics", Integer.valueOf(6)); m.put("com.codename1.annotations", Integer.valueOf(7)); - m.put("com.codename1.annotations.graphql", Integer.valueOf(8)); - m.put("com.codename1.annotations.grpc", Integer.valueOf(9)); - m.put("com.codename1.annotations.rest", Integer.valueOf(10)); - m.put("com.codename1.appreview", Integer.valueOf(11)); - m.put("com.codename1.ar", Integer.valueOf(12)); - m.put("com.codename1.background", Integer.valueOf(13)); - m.put("com.codename1.binding", Integer.valueOf(14)); - m.put("com.codename1.bluetooth", Integer.valueOf(15)); - m.put("com.codename1.bluetooth.classic", Integer.valueOf(16)); - m.put("com.codename1.bluetooth.gatt", Integer.valueOf(17)); - m.put("com.codename1.bluetooth.le", Integer.valueOf(18)); - m.put("com.codename1.bluetooth.le.server", Integer.valueOf(19)); - m.put("com.codename1.calendar", Integer.valueOf(20)); - m.put("com.codename1.camera", Integer.valueOf(21)); - m.put("com.codename1.capture", Integer.valueOf(22)); - m.put("com.codename1.car", Integer.valueOf(23)); - m.put("com.codename1.car.spi", Integer.valueOf(24)); - m.put("com.codename1.charts", Integer.valueOf(25)); - m.put("com.codename1.charts.compat", Integer.valueOf(26)); - m.put("com.codename1.charts.models", Integer.valueOf(27)); - m.put("com.codename1.charts.renderers", Integer.valueOf(28)); - m.put("com.codename1.charts.transitions", Integer.valueOf(29)); - m.put("com.codename1.charts.util", Integer.valueOf(30)); - m.put("com.codename1.charts.views", Integer.valueOf(31)); - m.put("com.codename1.cloud", Integer.valueOf(32)); - m.put("com.codename1.codescan", Integer.valueOf(33)); - m.put("com.codename1.compat.java.util", Integer.valueOf(34)); - m.put("com.codename1.components", Integer.valueOf(35)); - m.put("com.codename1.contacts", Integer.valueOf(36)); - m.put("com.codename1.crash", Integer.valueOf(37)); - m.put("com.codename1.db", Integer.valueOf(38)); - m.put("com.codename1.facebook", Integer.valueOf(39)); - m.put("com.codename1.facebook.ui", Integer.valueOf(40)); - m.put("com.codename1.gaming", Integer.valueOf(41)); - m.put("com.codename1.gaming.level", Integer.valueOf(42)); - m.put("com.codename1.gaming.physics", Integer.valueOf(43)); - m.put("com.codename1.gaming.physics.box2d.callbacks", Integer.valueOf(44)); - m.put("com.codename1.gaming.physics.box2d.collision", Integer.valueOf(45)); - m.put("com.codename1.gaming.physics.box2d.collision.broadphase", Integer.valueOf(46)); - m.put("com.codename1.gaming.physics.box2d.collision.shapes", Integer.valueOf(47)); - m.put("com.codename1.gaming.physics.box2d.common", Integer.valueOf(48)); - m.put("com.codename1.gaming.physics.box2d.dynamics", Integer.valueOf(49)); - m.put("com.codename1.gaming.physics.box2d.dynamics.contacts", Integer.valueOf(50)); - m.put("com.codename1.gaming.physics.box2d.dynamics.joints", Integer.valueOf(51)); - m.put("com.codename1.gaming.physics.box2d.pooling", Integer.valueOf(52)); - m.put("com.codename1.gaming.physics.box2d.pooling.arrays", Integer.valueOf(53)); - m.put("com.codename1.gaming.physics.box2d.pooling.normal", Integer.valueOf(54)); - m.put("com.codename1.gaming.physics.box2d.pooling.stacks", Integer.valueOf(55)); - m.put("com.codename1.gpu", Integer.valueOf(56)); - m.put("com.codename1.health", Integer.valueOf(57)); - m.put("com.codename1.health.nutrition", Integer.valueOf(58)); - m.put("com.codename1.health.sensors", Integer.valueOf(59)); - m.put("com.codename1.health.workout", Integer.valueOf(60)); - m.put("com.codename1.io", Integer.valueOf(61)); - m.put("com.codename1.io.bonjour", Integer.valueOf(62)); - m.put("com.codename1.io.graphql", Integer.valueOf(63)); - m.put("com.codename1.io.grpc", Integer.valueOf(64)); - m.put("com.codename1.io.gzip", Integer.valueOf(65)); - m.put("com.codename1.io.oidc", Integer.valueOf(66)); - m.put("com.codename1.io.rest", Integer.valueOf(67)); - m.put("com.codename1.io.services", Integer.valueOf(68)); - m.put("com.codename1.io.tar", Integer.valueOf(69)); - m.put("com.codename1.io.usb", Integer.valueOf(70)); - m.put("com.codename1.io.webauthn", Integer.valueOf(71)); - m.put("com.codename1.io.wifi", Integer.valueOf(72)); - m.put("com.codename1.javascript", Integer.valueOf(73)); - m.put("com.codename1.l10n", Integer.valueOf(74)); - m.put("com.codename1.location", Integer.valueOf(75)); - m.put("com.codename1.mapping", Integer.valueOf(76)); - m.put("com.codename1.maps", Integer.valueOf(77)); - m.put("com.codename1.maps.layers", Integer.valueOf(78)); - m.put("com.codename1.maps.providers", Integer.valueOf(79)); - m.put("com.codename1.maps.routing", Integer.valueOf(80)); - m.put("com.codename1.maps.spi", Integer.valueOf(81)); - m.put("com.codename1.maps.vector", Integer.valueOf(82)); - m.put("com.codename1.mcp", Integer.valueOf(83)); - m.put("com.codename1.media", Integer.valueOf(84)); - m.put("com.codename1.messaging", Integer.valueOf(85)); - m.put("com.codename1.nfc", Integer.valueOf(86)); - m.put("com.codename1.notifications", Integer.valueOf(87)); - m.put("com.codename1.orm", Integer.valueOf(88)); - m.put("com.codename1.payment", Integer.valueOf(89)); - m.put("com.codename1.plugin", Integer.valueOf(90)); - m.put("com.codename1.plugin.event", Integer.valueOf(91)); - m.put("com.codename1.printing", Integer.valueOf(92)); - m.put("com.codename1.processing", Integer.valueOf(93)); - m.put("com.codename1.properties", Integer.valueOf(94)); - m.put("com.codename1.push", Integer.valueOf(95)); - m.put("com.codename1.router", Integer.valueOf(96)); - m.put("com.codename1.security", Integer.valueOf(97)); - m.put("com.codename1.security.shield", Integer.valueOf(98)); - m.put("com.codename1.security.shield.spi", Integer.valueOf(99)); - m.put("com.codename1.sensors", Integer.valueOf(100)); - m.put("com.codename1.share", Integer.valueOf(101)); - m.put("com.codename1.social", Integer.valueOf(102)); - m.put("com.codename1.surfaces", Integer.valueOf(103)); - m.put("com.codename1.surfaces.spi", Integer.valueOf(104)); - m.put("com.codename1.system", Integer.valueOf(105)); - m.put("com.codename1.testing", Integer.valueOf(106)); - m.put("com.codename1.ui", Integer.valueOf(107)); - m.put("com.codename1.ui.accessibility", Integer.valueOf(108)); - m.put("com.codename1.ui.animations", Integer.valueOf(109)); - m.put("com.codename1.ui.css", Integer.valueOf(110)); - m.put("com.codename1.ui.editor", Integer.valueOf(111)); - m.put("com.codename1.ui.events", Integer.valueOf(112)); - m.put("com.codename1.ui.geom", Integer.valueOf(113)); - m.put("com.codename1.ui.html", Integer.valueOf(114)); - m.put("com.codename1.ui.layouts", Integer.valueOf(115)); - m.put("com.codename1.ui.layouts.mig", Integer.valueOf(116)); - m.put("com.codename1.ui.list", Integer.valueOf(117)); - m.put("com.codename1.ui.painter", Integer.valueOf(118)); - m.put("com.codename1.ui.plaf", Integer.valueOf(119)); - m.put("com.codename1.ui.scene", Integer.valueOf(120)); - m.put("com.codename1.ui.spinner", Integer.valueOf(121)); - m.put("com.codename1.ui.table", Integer.valueOf(122)); - m.put("com.codename1.ui.tree", Integer.valueOf(123)); - m.put("com.codename1.ui.util", Integer.valueOf(124)); - m.put("com.codename1.ui.validation", Integer.valueOf(125)); - m.put("com.codename1.util", Integer.valueOf(126)); - m.put("com.codename1.util.promise", Integer.valueOf(127)); - m.put("com.codename1.util.regex", Integer.valueOf(128)); - m.put("com.codename1.vr", Integer.valueOf(129)); - m.put("com.codename1.wearable", Integer.valueOf(130)); - m.put("com.codename1.wearable.spi", Integer.valueOf(131)); - m.put("com.codename1.xml", Integer.valueOf(132)); - m.put("com.codenameone.playground", Integer.valueOf(133)); - m.put("java.io", Integer.valueOf(134)); - m.put("java.lang", Integer.valueOf(135)); - m.put("java.lang.ref", Integer.valueOf(136)); - m.put("java.lang.reflect", Integer.valueOf(137)); - m.put("java.net", Integer.valueOf(138)); - m.put("java.nio.charset", Integer.valueOf(139)); - m.put("java.text", Integer.valueOf(140)); - m.put("java.time", Integer.valueOf(141)); - m.put("java.time.format", Integer.valueOf(142)); - m.put("java.time.temporal", Integer.valueOf(143)); - m.put("java.util", Integer.valueOf(144)); - m.put("java.util.concurrent", Integer.valueOf(145)); - m.put("java.util.concurrent.atomic", Integer.valueOf(146)); - m.put("java.util.function", Integer.valueOf(147)); - m.put("java.util.stream", Integer.valueOf(148)); + m.put("com.codename1.annotations.buildhints", Integer.valueOf(8)); + m.put("com.codename1.annotations.graphql", Integer.valueOf(9)); + m.put("com.codename1.annotations.grpc", Integer.valueOf(10)); + m.put("com.codename1.annotations.rest", Integer.valueOf(11)); + m.put("com.codename1.appreview", Integer.valueOf(12)); + m.put("com.codename1.ar", Integer.valueOf(13)); + m.put("com.codename1.background", Integer.valueOf(14)); + m.put("com.codename1.binding", Integer.valueOf(15)); + m.put("com.codename1.bluetooth", Integer.valueOf(16)); + m.put("com.codename1.bluetooth.classic", Integer.valueOf(17)); + m.put("com.codename1.bluetooth.gatt", Integer.valueOf(18)); + m.put("com.codename1.bluetooth.le", Integer.valueOf(19)); + m.put("com.codename1.bluetooth.le.server", Integer.valueOf(20)); + m.put("com.codename1.calendar", Integer.valueOf(21)); + m.put("com.codename1.camera", Integer.valueOf(22)); + m.put("com.codename1.capture", Integer.valueOf(23)); + m.put("com.codename1.car", Integer.valueOf(24)); + m.put("com.codename1.car.spi", Integer.valueOf(25)); + m.put("com.codename1.charts", Integer.valueOf(26)); + m.put("com.codename1.charts.compat", Integer.valueOf(27)); + m.put("com.codename1.charts.models", Integer.valueOf(28)); + m.put("com.codename1.charts.renderers", Integer.valueOf(29)); + m.put("com.codename1.charts.transitions", Integer.valueOf(30)); + m.put("com.codename1.charts.util", Integer.valueOf(31)); + m.put("com.codename1.charts.views", Integer.valueOf(32)); + m.put("com.codename1.cloud", Integer.valueOf(33)); + m.put("com.codename1.codescan", Integer.valueOf(34)); + m.put("com.codename1.compat.java.util", Integer.valueOf(35)); + m.put("com.codename1.components", Integer.valueOf(36)); + m.put("com.codename1.contacts", Integer.valueOf(37)); + m.put("com.codename1.crash", Integer.valueOf(38)); + m.put("com.codename1.db", Integer.valueOf(39)); + m.put("com.codename1.facebook", Integer.valueOf(40)); + m.put("com.codename1.facebook.ui", Integer.valueOf(41)); + m.put("com.codename1.gaming", Integer.valueOf(42)); + m.put("com.codename1.gaming.level", Integer.valueOf(43)); + m.put("com.codename1.gaming.physics", Integer.valueOf(44)); + m.put("com.codename1.gaming.physics.box2d.callbacks", Integer.valueOf(45)); + m.put("com.codename1.gaming.physics.box2d.collision", Integer.valueOf(46)); + m.put("com.codename1.gaming.physics.box2d.collision.broadphase", Integer.valueOf(47)); + m.put("com.codename1.gaming.physics.box2d.collision.shapes", Integer.valueOf(48)); + m.put("com.codename1.gaming.physics.box2d.common", Integer.valueOf(49)); + m.put("com.codename1.gaming.physics.box2d.dynamics", Integer.valueOf(50)); + m.put("com.codename1.gaming.physics.box2d.dynamics.contacts", Integer.valueOf(51)); + m.put("com.codename1.gaming.physics.box2d.dynamics.joints", Integer.valueOf(52)); + m.put("com.codename1.gaming.physics.box2d.pooling", Integer.valueOf(53)); + m.put("com.codename1.gaming.physics.box2d.pooling.arrays", Integer.valueOf(54)); + m.put("com.codename1.gaming.physics.box2d.pooling.normal", Integer.valueOf(55)); + m.put("com.codename1.gaming.physics.box2d.pooling.stacks", Integer.valueOf(56)); + m.put("com.codename1.gpu", Integer.valueOf(57)); + m.put("com.codename1.health", Integer.valueOf(58)); + m.put("com.codename1.health.nutrition", Integer.valueOf(59)); + m.put("com.codename1.health.sensors", Integer.valueOf(60)); + m.put("com.codename1.health.workout", Integer.valueOf(61)); + m.put("com.codename1.home", Integer.valueOf(62)); + m.put("com.codename1.home.commissioning", Integer.valueOf(63)); + m.put("com.codename1.home.spi", Integer.valueOf(64)); + m.put("com.codename1.intents", Integer.valueOf(65)); + m.put("com.codename1.intents.spi", Integer.valueOf(66)); + m.put("com.codename1.io", Integer.valueOf(67)); + m.put("com.codename1.io.bonjour", Integer.valueOf(68)); + m.put("com.codename1.io.graphql", Integer.valueOf(69)); + m.put("com.codename1.io.grpc", Integer.valueOf(70)); + m.put("com.codename1.io.gzip", Integer.valueOf(71)); + m.put("com.codename1.io.oidc", Integer.valueOf(72)); + m.put("com.codename1.io.rest", Integer.valueOf(73)); + m.put("com.codename1.io.services", Integer.valueOf(74)); + m.put("com.codename1.io.tar", Integer.valueOf(75)); + m.put("com.codename1.io.usb", Integer.valueOf(76)); + m.put("com.codename1.io.webauthn", Integer.valueOf(77)); + m.put("com.codename1.io.wifi", Integer.valueOf(78)); + m.put("com.codename1.javascript", Integer.valueOf(79)); + m.put("com.codename1.l10n", Integer.valueOf(80)); + m.put("com.codename1.location", Integer.valueOf(81)); + m.put("com.codename1.mapping", Integer.valueOf(82)); + m.put("com.codename1.maps", Integer.valueOf(83)); + m.put("com.codename1.maps.layers", Integer.valueOf(84)); + m.put("com.codename1.maps.providers", Integer.valueOf(85)); + m.put("com.codename1.maps.routing", Integer.valueOf(86)); + m.put("com.codename1.maps.spi", Integer.valueOf(87)); + m.put("com.codename1.maps.vector", Integer.valueOf(88)); + m.put("com.codename1.mcp", Integer.valueOf(89)); + m.put("com.codename1.media", Integer.valueOf(90)); + m.put("com.codename1.messaging", Integer.valueOf(91)); + m.put("com.codename1.nfc", Integer.valueOf(92)); + m.put("com.codename1.notifications", Integer.valueOf(93)); + m.put("com.codename1.orm", Integer.valueOf(94)); + m.put("com.codename1.payment", Integer.valueOf(95)); + m.put("com.codename1.plugin", Integer.valueOf(96)); + m.put("com.codename1.plugin.event", Integer.valueOf(97)); + m.put("com.codename1.printing", Integer.valueOf(98)); + m.put("com.codename1.processing", Integer.valueOf(99)); + m.put("com.codename1.properties", Integer.valueOf(100)); + m.put("com.codename1.push", Integer.valueOf(101)); + m.put("com.codename1.router", Integer.valueOf(102)); + m.put("com.codename1.security", Integer.valueOf(103)); + m.put("com.codename1.security.hardening", Integer.valueOf(104)); + m.put("com.codename1.security.shield", Integer.valueOf(105)); + m.put("com.codename1.security.shield.spi", Integer.valueOf(106)); + m.put("com.codename1.sensors", Integer.valueOf(107)); + m.put("com.codename1.share", Integer.valueOf(108)); + m.put("com.codename1.social", Integer.valueOf(109)); + m.put("com.codename1.surfaces", Integer.valueOf(110)); + m.put("com.codename1.surfaces.spi", Integer.valueOf(111)); + m.put("com.codename1.system", Integer.valueOf(112)); + m.put("com.codename1.testing", Integer.valueOf(113)); + m.put("com.codename1.ui", Integer.valueOf(114)); + m.put("com.codename1.ui.accessibility", Integer.valueOf(115)); + m.put("com.codename1.ui.animations", Integer.valueOf(116)); + m.put("com.codename1.ui.css", Integer.valueOf(117)); + m.put("com.codename1.ui.editor", Integer.valueOf(118)); + m.put("com.codename1.ui.events", Integer.valueOf(119)); + m.put("com.codename1.ui.geom", Integer.valueOf(120)); + m.put("com.codename1.ui.html", Integer.valueOf(121)); + m.put("com.codename1.ui.layouts", Integer.valueOf(122)); + m.put("com.codename1.ui.layouts.mig", Integer.valueOf(123)); + m.put("com.codename1.ui.list", Integer.valueOf(124)); + m.put("com.codename1.ui.painter", Integer.valueOf(125)); + m.put("com.codename1.ui.plaf", Integer.valueOf(126)); + m.put("com.codename1.ui.scene", Integer.valueOf(127)); + m.put("com.codename1.ui.spinner", Integer.valueOf(128)); + m.put("com.codename1.ui.table", Integer.valueOf(129)); + m.put("com.codename1.ui.tree", Integer.valueOf(130)); + m.put("com.codename1.ui.util", Integer.valueOf(131)); + m.put("com.codename1.ui.validation", Integer.valueOf(132)); + m.put("com.codename1.util", Integer.valueOf(133)); + m.put("com.codename1.util.promise", Integer.valueOf(134)); + m.put("com.codename1.util.regex", Integer.valueOf(135)); + m.put("com.codename1.vr", Integer.valueOf(136)); + m.put("com.codename1.wearable", Integer.valueOf(137)); + m.put("com.codename1.wearable.spi", Integer.valueOf(138)); + m.put("com.codename1.xml", Integer.valueOf(139)); + m.put("com.codenameone.playground", Integer.valueOf(140)); + m.put("java.io", Integer.valueOf(141)); + m.put("java.lang", Integer.valueOf(142)); + m.put("java.lang.ref", Integer.valueOf(143)); + m.put("java.lang.reflect", Integer.valueOf(144)); + m.put("java.net", Integer.valueOf(145)); + m.put("java.nio.charset", Integer.valueOf(146)); + m.put("java.text", Integer.valueOf(147)); + m.put("java.time", Integer.valueOf(148)); + m.put("java.time.format", Integer.valueOf(149)); + m.put("java.time.temporal", Integer.valueOf(150)); + m.put("java.util", Integer.valueOf(151)); + m.put("java.util.concurrent", Integer.valueOf(152)); + m.put("java.util.concurrent.atomic", Integer.valueOf(153)); + m.put("java.util.function", Integer.valueOf(154)); + m.put("java.util.stream", Integer.valueOf(155)); return m; } - private static final int PACKAGE_HANDLER_COUNT = 149; + private static final int PACKAGE_HANDLER_COUNT = 156; @Override public Object invoke(Object target, String name, Object[] args) throws Exception { @@ -7594,147 +7996,154 @@ private static Object dispatchInstance(int __idx, Object target, String name, Ob case 5: return GeneratedAccess_com_codename1_ai_vision.invoke(target, name, args); case 6: return GeneratedAccess_com_codename1_analytics.invoke(target, name, args); case 7: return GeneratedAccess_com_codename1_annotations.invoke(target, name, args); - case 8: return GeneratedAccess_com_codename1_annotations_graphql.invoke(target, name, args); - case 9: return GeneratedAccess_com_codename1_annotations_grpc.invoke(target, name, args); - case 10: return GeneratedAccess_com_codename1_annotations_rest.invoke(target, name, args); - case 11: return GeneratedAccess_com_codename1_appreview.invoke(target, name, args); - case 12: return GeneratedAccess_com_codename1_ar.invoke(target, name, args); - case 13: return GeneratedAccess_com_codename1_background.invoke(target, name, args); - case 14: return GeneratedAccess_com_codename1_binding.invoke(target, name, args); - case 15: return GeneratedAccess_com_codename1_bluetooth.invoke(target, name, args); - case 16: return GeneratedAccess_com_codename1_bluetooth_classic.invoke(target, name, args); - case 17: return GeneratedAccess_com_codename1_bluetooth_gatt.invoke(target, name, args); - case 18: return GeneratedAccess_com_codename1_bluetooth_le.invoke(target, name, args); - case 19: return GeneratedAccess_com_codename1_bluetooth_le_server.invoke(target, name, args); - case 20: return GeneratedAccess_com_codename1_calendar.invoke(target, name, args); - case 21: return GeneratedAccess_com_codename1_camera.invoke(target, name, args); - case 22: return GeneratedAccess_com_codename1_capture.invoke(target, name, args); - case 23: return GeneratedAccess_com_codename1_car.invoke(target, name, args); - case 24: return GeneratedAccess_com_codename1_car_spi.invoke(target, name, args); - case 25: return GeneratedAccess_com_codename1_charts.invoke(target, name, args); - case 26: return GeneratedAccess_com_codename1_charts_compat.invoke(target, name, args); - case 27: return GeneratedAccess_com_codename1_charts_models.invoke(target, name, args); - case 28: return GeneratedAccess_com_codename1_charts_renderers.invoke(target, name, args); - case 29: return GeneratedAccess_com_codename1_charts_transitions.invoke(target, name, args); - case 30: return GeneratedAccess_com_codename1_charts_util.invoke(target, name, args); - case 31: return GeneratedAccess_com_codename1_charts_views.invoke(target, name, args); - case 32: return GeneratedAccess_com_codename1_cloud.invoke(target, name, args); - case 33: return GeneratedAccess_com_codename1_codescan.invoke(target, name, args); - case 34: return GeneratedAccess_com_codename1_compat_java_util.invoke(target, name, args); - case 35: return GeneratedAccess_com_codename1_components.invoke(target, name, args); - case 36: return GeneratedAccess_com_codename1_contacts.invoke(target, name, args); - case 37: return GeneratedAccess_com_codename1_crash.invoke(target, name, args); - case 38: return GeneratedAccess_com_codename1_db.invoke(target, name, args); - case 39: return GeneratedAccess_com_codename1_facebook.invoke(target, name, args); - case 40: return GeneratedAccess_com_codename1_facebook_ui.invoke(target, name, args); - case 41: return GeneratedAccess_com_codename1_gaming.invoke(target, name, args); - case 42: return GeneratedAccess_com_codename1_gaming_level.invoke(target, name, args); - case 43: return GeneratedAccess_com_codename1_gaming_physics.invoke(target, name, args); - case 44: return GeneratedAccess_com_codename1_gaming_physics_box2d_callbacks.invoke(target, name, args); - case 45: return GeneratedAccess_com_codename1_gaming_physics_box2d_collision.invoke(target, name, args); - case 46: return GeneratedAccess_com_codename1_gaming_physics_box2d_collision_broadphase.invoke(target, name, args); - case 47: return GeneratedAccess_com_codename1_gaming_physics_box2d_collision_shapes.invoke(target, name, args); - case 48: return GeneratedAccess_com_codename1_gaming_physics_box2d_common.invoke(target, name, args); - case 49: return GeneratedAccess_com_codename1_gaming_physics_box2d_dynamics.invoke(target, name, args); - case 50: return GeneratedAccess_com_codename1_gaming_physics_box2d_dynamics_contacts.invoke(target, name, args); - case 51: return GeneratedAccess_com_codename1_gaming_physics_box2d_dynamics_joints.invoke(target, name, args); - case 52: return GeneratedAccess_com_codename1_gaming_physics_box2d_pooling.invoke(target, name, args); - case 53: return GeneratedAccess_com_codename1_gaming_physics_box2d_pooling_arrays.invoke(target, name, args); - case 54: return GeneratedAccess_com_codename1_gaming_physics_box2d_pooling_normal.invoke(target, name, args); - case 55: return GeneratedAccess_com_codename1_gaming_physics_box2d_pooling_stacks.invoke(target, name, args); - case 56: return GeneratedAccess_com_codename1_gpu.invoke(target, name, args); - case 57: return GeneratedAccess_com_codename1_health.invoke(target, name, args); - case 58: return GeneratedAccess_com_codename1_health_nutrition.invoke(target, name, args); - case 59: return GeneratedAccess_com_codename1_health_sensors.invoke(target, name, args); - case 60: return GeneratedAccess_com_codename1_health_workout.invoke(target, name, args); - case 61: return GeneratedAccess_com_codename1_io.invoke(target, name, args); - case 62: return GeneratedAccess_com_codename1_io_bonjour.invoke(target, name, args); - case 63: return GeneratedAccess_com_codename1_io_graphql.invoke(target, name, args); - case 64: return GeneratedAccess_com_codename1_io_grpc.invoke(target, name, args); - case 65: return GeneratedAccess_com_codename1_io_gzip.invoke(target, name, args); - case 66: return GeneratedAccess_com_codename1_io_oidc.invoke(target, name, args); - case 67: return GeneratedAccess_com_codename1_io_rest.invoke(target, name, args); - case 68: return GeneratedAccess_com_codename1_io_services.invoke(target, name, args); - case 69: return GeneratedAccess_com_codename1_io_tar.invoke(target, name, args); - case 70: return GeneratedAccess_com_codename1_io_usb.invoke(target, name, args); - case 71: return GeneratedAccess_com_codename1_io_webauthn.invoke(target, name, args); - case 72: return GeneratedAccess_com_codename1_io_wifi.invoke(target, name, args); - case 73: return GeneratedAccess_com_codename1_javascript.invoke(target, name, args); - case 74: return GeneratedAccess_com_codename1_l10n.invoke(target, name, args); - case 75: return GeneratedAccess_com_codename1_location.invoke(target, name, args); - case 76: return GeneratedAccess_com_codename1_mapping.invoke(target, name, args); - case 77: return GeneratedAccess_com_codename1_maps.invoke(target, name, args); - case 78: return GeneratedAccess_com_codename1_maps_layers.invoke(target, name, args); - case 79: return GeneratedAccess_com_codename1_maps_providers.invoke(target, name, args); - case 80: return GeneratedAccess_com_codename1_maps_routing.invoke(target, name, args); - case 81: return GeneratedAccess_com_codename1_maps_spi.invoke(target, name, args); - case 82: return GeneratedAccess_com_codename1_maps_vector.invoke(target, name, args); - case 83: return GeneratedAccess_com_codename1_mcp.invoke(target, name, args); - case 84: return GeneratedAccess_com_codename1_media.invoke(target, name, args); - case 85: return GeneratedAccess_com_codename1_messaging.invoke(target, name, args); - case 86: return GeneratedAccess_com_codename1_nfc.invoke(target, name, args); - case 87: return GeneratedAccess_com_codename1_notifications.invoke(target, name, args); - case 88: return GeneratedAccess_com_codename1_orm.invoke(target, name, args); - case 89: return GeneratedAccess_com_codename1_payment.invoke(target, name, args); - case 90: return GeneratedAccess_com_codename1_plugin.invoke(target, name, args); - case 91: return GeneratedAccess_com_codename1_plugin_event.invoke(target, name, args); - case 92: return GeneratedAccess_com_codename1_printing.invoke(target, name, args); - case 93: return GeneratedAccess_com_codename1_processing.invoke(target, name, args); - case 94: return GeneratedAccess_com_codename1_properties.invoke(target, name, args); - case 95: return GeneratedAccess_com_codename1_push.invoke(target, name, args); - case 96: return GeneratedAccess_com_codename1_router.invoke(target, name, args); - case 97: return GeneratedAccess_com_codename1_security.invoke(target, name, args); - case 98: return GeneratedAccess_com_codename1_security_shield.invoke(target, name, args); - case 99: return GeneratedAccess_com_codename1_security_shield_spi.invoke(target, name, args); - case 100: return GeneratedAccess_com_codename1_sensors.invoke(target, name, args); - case 101: return GeneratedAccess_com_codename1_share.invoke(target, name, args); - case 102: return GeneratedAccess_com_codename1_social.invoke(target, name, args); - case 103: return GeneratedAccess_com_codename1_surfaces.invoke(target, name, args); - case 104: return GeneratedAccess_com_codename1_surfaces_spi.invoke(target, name, args); - case 105: return GeneratedAccess_com_codename1_system.invoke(target, name, args); - case 106: return GeneratedAccess_com_codename1_testing.invoke(target, name, args); - case 107: return GeneratedAccess_com_codename1_ui.invoke(target, name, args); - case 108: return GeneratedAccess_com_codename1_ui_accessibility.invoke(target, name, args); - case 109: return GeneratedAccess_com_codename1_ui_animations.invoke(target, name, args); - case 110: return GeneratedAccess_com_codename1_ui_css.invoke(target, name, args); - case 111: return GeneratedAccess_com_codename1_ui_editor.invoke(target, name, args); - case 112: return GeneratedAccess_com_codename1_ui_events.invoke(target, name, args); - case 113: return GeneratedAccess_com_codename1_ui_geom.invoke(target, name, args); - case 114: return GeneratedAccess_com_codename1_ui_html.invoke(target, name, args); - case 115: return GeneratedAccess_com_codename1_ui_layouts.invoke(target, name, args); - case 116: return GeneratedAccess_com_codename1_ui_layouts_mig.invoke(target, name, args); - case 117: return GeneratedAccess_com_codename1_ui_list.invoke(target, name, args); - case 118: return GeneratedAccess_com_codename1_ui_painter.invoke(target, name, args); - case 119: return GeneratedAccess_com_codename1_ui_plaf.invoke(target, name, args); - case 120: return GeneratedAccess_com_codename1_ui_scene.invoke(target, name, args); - case 121: return GeneratedAccess_com_codename1_ui_spinner.invoke(target, name, args); - case 122: return GeneratedAccess_com_codename1_ui_table.invoke(target, name, args); - case 123: return GeneratedAccess_com_codename1_ui_tree.invoke(target, name, args); - case 124: return GeneratedAccess_com_codename1_ui_util.invoke(target, name, args); - case 125: return GeneratedAccess_com_codename1_ui_validation.invoke(target, name, args); - case 126: return GeneratedAccess_com_codename1_util.invoke(target, name, args); - case 127: return GeneratedAccess_com_codename1_util_promise.invoke(target, name, args); - case 128: return GeneratedAccess_com_codename1_util_regex.invoke(target, name, args); - case 129: return GeneratedAccess_com_codename1_vr.invoke(target, name, args); - case 130: return GeneratedAccess_com_codename1_wearable.invoke(target, name, args); - case 131: return GeneratedAccess_com_codename1_wearable_spi.invoke(target, name, args); - case 132: return GeneratedAccess_com_codename1_xml.invoke(target, name, args); - case 133: return GeneratedAccess_com_codenameone_playground.invoke(target, name, args); - case 134: return GeneratedAccess_java_io.invoke(target, name, args); - case 135: return GeneratedAccess_java_lang.invoke(target, name, args); - case 136: return GeneratedAccess_java_lang_ref.invoke(target, name, args); - case 137: return GeneratedAccess_java_lang_reflect.invoke(target, name, args); - case 138: return GeneratedAccess_java_net.invoke(target, name, args); - case 139: return GeneratedAccess_java_nio_charset.invoke(target, name, args); - case 140: return GeneratedAccess_java_text.invoke(target, name, args); - case 141: return GeneratedAccess_java_time.invoke(target, name, args); - case 142: return GeneratedAccess_java_time_format.invoke(target, name, args); - case 143: return GeneratedAccess_java_time_temporal.invoke(target, name, args); - case 144: return GeneratedAccess_java_util.invoke(target, name, args); - case 145: return GeneratedAccess_java_util_concurrent.invoke(target, name, args); - case 146: return GeneratedAccess_java_util_concurrent_atomic.invoke(target, name, args); - case 147: return GeneratedAccess_java_util_function.invoke(target, name, args); - case 148: return GeneratedAccess_java_util_stream.invoke(target, name, args); + case 8: return GeneratedAccess_com_codename1_annotations_buildhints.invoke(target, name, args); + case 9: return GeneratedAccess_com_codename1_annotations_graphql.invoke(target, name, args); + case 10: return GeneratedAccess_com_codename1_annotations_grpc.invoke(target, name, args); + case 11: return GeneratedAccess_com_codename1_annotations_rest.invoke(target, name, args); + case 12: return GeneratedAccess_com_codename1_appreview.invoke(target, name, args); + case 13: return GeneratedAccess_com_codename1_ar.invoke(target, name, args); + case 14: return GeneratedAccess_com_codename1_background.invoke(target, name, args); + case 15: return GeneratedAccess_com_codename1_binding.invoke(target, name, args); + case 16: return GeneratedAccess_com_codename1_bluetooth.invoke(target, name, args); + case 17: return GeneratedAccess_com_codename1_bluetooth_classic.invoke(target, name, args); + case 18: return GeneratedAccess_com_codename1_bluetooth_gatt.invoke(target, name, args); + case 19: return GeneratedAccess_com_codename1_bluetooth_le.invoke(target, name, args); + case 20: return GeneratedAccess_com_codename1_bluetooth_le_server.invoke(target, name, args); + case 21: return GeneratedAccess_com_codename1_calendar.invoke(target, name, args); + case 22: return GeneratedAccess_com_codename1_camera.invoke(target, name, args); + case 23: return GeneratedAccess_com_codename1_capture.invoke(target, name, args); + case 24: return GeneratedAccess_com_codename1_car.invoke(target, name, args); + case 25: return GeneratedAccess_com_codename1_car_spi.invoke(target, name, args); + case 26: return GeneratedAccess_com_codename1_charts.invoke(target, name, args); + case 27: return GeneratedAccess_com_codename1_charts_compat.invoke(target, name, args); + case 28: return GeneratedAccess_com_codename1_charts_models.invoke(target, name, args); + case 29: return GeneratedAccess_com_codename1_charts_renderers.invoke(target, name, args); + case 30: return GeneratedAccess_com_codename1_charts_transitions.invoke(target, name, args); + case 31: return GeneratedAccess_com_codename1_charts_util.invoke(target, name, args); + case 32: return GeneratedAccess_com_codename1_charts_views.invoke(target, name, args); + case 33: return GeneratedAccess_com_codename1_cloud.invoke(target, name, args); + case 34: return GeneratedAccess_com_codename1_codescan.invoke(target, name, args); + case 35: return GeneratedAccess_com_codename1_compat_java_util.invoke(target, name, args); + case 36: return GeneratedAccess_com_codename1_components.invoke(target, name, args); + case 37: return GeneratedAccess_com_codename1_contacts.invoke(target, name, args); + case 38: return GeneratedAccess_com_codename1_crash.invoke(target, name, args); + case 39: return GeneratedAccess_com_codename1_db.invoke(target, name, args); + case 40: return GeneratedAccess_com_codename1_facebook.invoke(target, name, args); + case 41: return GeneratedAccess_com_codename1_facebook_ui.invoke(target, name, args); + case 42: return GeneratedAccess_com_codename1_gaming.invoke(target, name, args); + case 43: return GeneratedAccess_com_codename1_gaming_level.invoke(target, name, args); + case 44: return GeneratedAccess_com_codename1_gaming_physics.invoke(target, name, args); + case 45: return GeneratedAccess_com_codename1_gaming_physics_box2d_callbacks.invoke(target, name, args); + case 46: return GeneratedAccess_com_codename1_gaming_physics_box2d_collision.invoke(target, name, args); + case 47: return GeneratedAccess_com_codename1_gaming_physics_box2d_collision_broadphase.invoke(target, name, args); + case 48: return GeneratedAccess_com_codename1_gaming_physics_box2d_collision_shapes.invoke(target, name, args); + case 49: return GeneratedAccess_com_codename1_gaming_physics_box2d_common.invoke(target, name, args); + case 50: return GeneratedAccess_com_codename1_gaming_physics_box2d_dynamics.invoke(target, name, args); + case 51: return GeneratedAccess_com_codename1_gaming_physics_box2d_dynamics_contacts.invoke(target, name, args); + case 52: return GeneratedAccess_com_codename1_gaming_physics_box2d_dynamics_joints.invoke(target, name, args); + case 53: return GeneratedAccess_com_codename1_gaming_physics_box2d_pooling.invoke(target, name, args); + case 54: return GeneratedAccess_com_codename1_gaming_physics_box2d_pooling_arrays.invoke(target, name, args); + case 55: return GeneratedAccess_com_codename1_gaming_physics_box2d_pooling_normal.invoke(target, name, args); + case 56: return GeneratedAccess_com_codename1_gaming_physics_box2d_pooling_stacks.invoke(target, name, args); + case 57: return GeneratedAccess_com_codename1_gpu.invoke(target, name, args); + case 58: return GeneratedAccess_com_codename1_health.invoke(target, name, args); + case 59: return GeneratedAccess_com_codename1_health_nutrition.invoke(target, name, args); + case 60: return GeneratedAccess_com_codename1_health_sensors.invoke(target, name, args); + case 61: return GeneratedAccess_com_codename1_health_workout.invoke(target, name, args); + case 62: return GeneratedAccess_com_codename1_home.invoke(target, name, args); + case 63: return GeneratedAccess_com_codename1_home_commissioning.invoke(target, name, args); + case 64: return GeneratedAccess_com_codename1_home_spi.invoke(target, name, args); + case 65: return GeneratedAccess_com_codename1_intents.invoke(target, name, args); + case 66: return GeneratedAccess_com_codename1_intents_spi.invoke(target, name, args); + case 67: return GeneratedAccess_com_codename1_io.invoke(target, name, args); + case 68: return GeneratedAccess_com_codename1_io_bonjour.invoke(target, name, args); + case 69: return GeneratedAccess_com_codename1_io_graphql.invoke(target, name, args); + case 70: return GeneratedAccess_com_codename1_io_grpc.invoke(target, name, args); + case 71: return GeneratedAccess_com_codename1_io_gzip.invoke(target, name, args); + case 72: return GeneratedAccess_com_codename1_io_oidc.invoke(target, name, args); + case 73: return GeneratedAccess_com_codename1_io_rest.invoke(target, name, args); + case 74: return GeneratedAccess_com_codename1_io_services.invoke(target, name, args); + case 75: return GeneratedAccess_com_codename1_io_tar.invoke(target, name, args); + case 76: return GeneratedAccess_com_codename1_io_usb.invoke(target, name, args); + case 77: return GeneratedAccess_com_codename1_io_webauthn.invoke(target, name, args); + case 78: return GeneratedAccess_com_codename1_io_wifi.invoke(target, name, args); + case 79: return GeneratedAccess_com_codename1_javascript.invoke(target, name, args); + case 80: return GeneratedAccess_com_codename1_l10n.invoke(target, name, args); + case 81: return GeneratedAccess_com_codename1_location.invoke(target, name, args); + case 82: return GeneratedAccess_com_codename1_mapping.invoke(target, name, args); + case 83: return GeneratedAccess_com_codename1_maps.invoke(target, name, args); + case 84: return GeneratedAccess_com_codename1_maps_layers.invoke(target, name, args); + case 85: return GeneratedAccess_com_codename1_maps_providers.invoke(target, name, args); + case 86: return GeneratedAccess_com_codename1_maps_routing.invoke(target, name, args); + case 87: return GeneratedAccess_com_codename1_maps_spi.invoke(target, name, args); + case 88: return GeneratedAccess_com_codename1_maps_vector.invoke(target, name, args); + case 89: return GeneratedAccess_com_codename1_mcp.invoke(target, name, args); + case 90: return GeneratedAccess_com_codename1_media.invoke(target, name, args); + case 91: return GeneratedAccess_com_codename1_messaging.invoke(target, name, args); + case 92: return GeneratedAccess_com_codename1_nfc.invoke(target, name, args); + case 93: return GeneratedAccess_com_codename1_notifications.invoke(target, name, args); + case 94: return GeneratedAccess_com_codename1_orm.invoke(target, name, args); + case 95: return GeneratedAccess_com_codename1_payment.invoke(target, name, args); + case 96: return GeneratedAccess_com_codename1_plugin.invoke(target, name, args); + case 97: return GeneratedAccess_com_codename1_plugin_event.invoke(target, name, args); + case 98: return GeneratedAccess_com_codename1_printing.invoke(target, name, args); + case 99: return GeneratedAccess_com_codename1_processing.invoke(target, name, args); + case 100: return GeneratedAccess_com_codename1_properties.invoke(target, name, args); + case 101: return GeneratedAccess_com_codename1_push.invoke(target, name, args); + case 102: return GeneratedAccess_com_codename1_router.invoke(target, name, args); + case 103: return GeneratedAccess_com_codename1_security.invoke(target, name, args); + case 104: return GeneratedAccess_com_codename1_security_hardening.invoke(target, name, args); + case 105: return GeneratedAccess_com_codename1_security_shield.invoke(target, name, args); + case 106: return GeneratedAccess_com_codename1_security_shield_spi.invoke(target, name, args); + case 107: return GeneratedAccess_com_codename1_sensors.invoke(target, name, args); + case 108: return GeneratedAccess_com_codename1_share.invoke(target, name, args); + case 109: return GeneratedAccess_com_codename1_social.invoke(target, name, args); + case 110: return GeneratedAccess_com_codename1_surfaces.invoke(target, name, args); + case 111: return GeneratedAccess_com_codename1_surfaces_spi.invoke(target, name, args); + case 112: return GeneratedAccess_com_codename1_system.invoke(target, name, args); + case 113: return GeneratedAccess_com_codename1_testing.invoke(target, name, args); + case 114: return GeneratedAccess_com_codename1_ui.invoke(target, name, args); + case 115: return GeneratedAccess_com_codename1_ui_accessibility.invoke(target, name, args); + case 116: return GeneratedAccess_com_codename1_ui_animations.invoke(target, name, args); + case 117: return GeneratedAccess_com_codename1_ui_css.invoke(target, name, args); + case 118: return GeneratedAccess_com_codename1_ui_editor.invoke(target, name, args); + case 119: return GeneratedAccess_com_codename1_ui_events.invoke(target, name, args); + case 120: return GeneratedAccess_com_codename1_ui_geom.invoke(target, name, args); + case 121: return GeneratedAccess_com_codename1_ui_html.invoke(target, name, args); + case 122: return GeneratedAccess_com_codename1_ui_layouts.invoke(target, name, args); + case 123: return GeneratedAccess_com_codename1_ui_layouts_mig.invoke(target, name, args); + case 124: return GeneratedAccess_com_codename1_ui_list.invoke(target, name, args); + case 125: return GeneratedAccess_com_codename1_ui_painter.invoke(target, name, args); + case 126: return GeneratedAccess_com_codename1_ui_plaf.invoke(target, name, args); + case 127: return GeneratedAccess_com_codename1_ui_scene.invoke(target, name, args); + case 128: return GeneratedAccess_com_codename1_ui_spinner.invoke(target, name, args); + case 129: return GeneratedAccess_com_codename1_ui_table.invoke(target, name, args); + case 130: return GeneratedAccess_com_codename1_ui_tree.invoke(target, name, args); + case 131: return GeneratedAccess_com_codename1_ui_util.invoke(target, name, args); + case 132: return GeneratedAccess_com_codename1_ui_validation.invoke(target, name, args); + case 133: return GeneratedAccess_com_codename1_util.invoke(target, name, args); + case 134: return GeneratedAccess_com_codename1_util_promise.invoke(target, name, args); + case 135: return GeneratedAccess_com_codename1_util_regex.invoke(target, name, args); + case 136: return GeneratedAccess_com_codename1_vr.invoke(target, name, args); + case 137: return GeneratedAccess_com_codename1_wearable.invoke(target, name, args); + case 138: return GeneratedAccess_com_codename1_wearable_spi.invoke(target, name, args); + case 139: return GeneratedAccess_com_codename1_xml.invoke(target, name, args); + case 140: return GeneratedAccess_com_codenameone_playground.invoke(target, name, args); + case 141: return GeneratedAccess_java_io.invoke(target, name, args); + case 142: return GeneratedAccess_java_lang.invoke(target, name, args); + case 143: return GeneratedAccess_java_lang_ref.invoke(target, name, args); + case 144: return GeneratedAccess_java_lang_reflect.invoke(target, name, args); + case 145: return GeneratedAccess_java_net.invoke(target, name, args); + case 146: return GeneratedAccess_java_nio_charset.invoke(target, name, args); + case 147: return GeneratedAccess_java_text.invoke(target, name, args); + case 148: return GeneratedAccess_java_time.invoke(target, name, args); + case 149: return GeneratedAccess_java_time_format.invoke(target, name, args); + case 150: return GeneratedAccess_java_time_temporal.invoke(target, name, args); + case 151: return GeneratedAccess_java_util.invoke(target, name, args); + case 152: return GeneratedAccess_java_util_concurrent.invoke(target, name, args); + case 153: return GeneratedAccess_java_util_concurrent_atomic.invoke(target, name, args); + case 154: return GeneratedAccess_java_util_function.invoke(target, name, args); + case 155: return GeneratedAccess_java_util_stream.invoke(target, name, args); default: throw new CN1AccessException("no instance handler for index " + __idx); } } @@ -7779,6 +8188,9 @@ public Object getStaticField(Class type, String name) throws Exception { if ("com.codename1.annotations".equals(candidate)) { return GeneratedAccess_com_codename1_annotations.getStaticField(type, name); } + if ("com.codename1.annotations.buildhints".equals(candidate)) { + return GeneratedAccess_com_codename1_annotations_buildhints.getStaticField(type, name); + } if ("com.codename1.annotations.graphql".equals(candidate)) { return GeneratedAccess_com_codename1_annotations_graphql.getStaticField(type, name); } @@ -7938,6 +8350,21 @@ public Object getStaticField(Class type, String name) throws Exception { if ("com.codename1.health.workout".equals(candidate)) { return GeneratedAccess_com_codename1_health_workout.getStaticField(type, name); } + if ("com.codename1.home".equals(candidate)) { + return GeneratedAccess_com_codename1_home.getStaticField(type, name); + } + if ("com.codename1.home.commissioning".equals(candidate)) { + return GeneratedAccess_com_codename1_home_commissioning.getStaticField(type, name); + } + if ("com.codename1.home.spi".equals(candidate)) { + return GeneratedAccess_com_codename1_home_spi.getStaticField(type, name); + } + if ("com.codename1.intents".equals(candidate)) { + return GeneratedAccess_com_codename1_intents.getStaticField(type, name); + } + if ("com.codename1.intents.spi".equals(candidate)) { + return GeneratedAccess_com_codename1_intents_spi.getStaticField(type, name); + } if ("com.codename1.io".equals(candidate)) { return GeneratedAccess_com_codename1_io.getStaticField(type, name); } @@ -8049,6 +8476,9 @@ public Object getStaticField(Class type, String name) throws Exception { if ("com.codename1.security".equals(candidate)) { return GeneratedAccess_com_codename1_security.getStaticField(type, name); } + if ("com.codename1.security.hardening".equals(candidate)) { + return GeneratedAccess_com_codename1_security_hardening.getStaticField(type, name); + } if ("com.codename1.security.shield".equals(candidate)) { return GeneratedAccess_com_codename1_security_shield.getStaticField(type, name); } @@ -8251,6 +8681,11 @@ public Object getField(Object target, String name) throws Exception { } catch (CN1AccessException ex) { unsupported = ex; } + try { + return GeneratedAccess_com_codename1_annotations_buildhints.getField(target, name); + } catch (CN1AccessException ex) { + unsupported = ex; + } try { return GeneratedAccess_com_codename1_annotations_graphql.getField(target, name); } catch (CN1AccessException ex) { @@ -8516,6 +8951,31 @@ public Object getField(Object target, String name) throws Exception { } catch (CN1AccessException ex) { unsupported = ex; } + try { + return GeneratedAccess_com_codename1_home.getField(target, name); + } catch (CN1AccessException ex) { + unsupported = ex; + } + try { + return GeneratedAccess_com_codename1_home_commissioning.getField(target, name); + } catch (CN1AccessException ex) { + unsupported = ex; + } + try { + return GeneratedAccess_com_codename1_home_spi.getField(target, name); + } catch (CN1AccessException ex) { + unsupported = ex; + } + try { + return GeneratedAccess_com_codename1_intents.getField(target, name); + } catch (CN1AccessException ex) { + unsupported = ex; + } + try { + return GeneratedAccess_com_codename1_intents_spi.getField(target, name); + } catch (CN1AccessException ex) { + unsupported = ex; + } try { return GeneratedAccess_com_codename1_io.getField(target, name); } catch (CN1AccessException ex) { @@ -8701,6 +9161,11 @@ public Object getField(Object target, String name) throws Exception { } catch (CN1AccessException ex) { unsupported = ex; } + try { + return GeneratedAccess_com_codename1_security_hardening.getField(target, name); + } catch (CN1AccessException ex) { + unsupported = ex; + } try { return GeneratedAccess_com_codename1_security_shield.getField(target, name); } catch (CN1AccessException ex) { @@ -8998,6 +9463,10 @@ public void setStaticField(Class type, String name, Object value) throws Exce GeneratedAccess_com_codename1_annotations.setStaticField(type, name, value); return; } + if ("com.codename1.annotations.buildhints".equals(candidate)) { + GeneratedAccess_com_codename1_annotations_buildhints.setStaticField(type, name, value); + return; + } if ("com.codename1.annotations.graphql".equals(candidate)) { GeneratedAccess_com_codename1_annotations_graphql.setStaticField(type, name, value); return; @@ -9210,6 +9679,26 @@ public void setStaticField(Class type, String name, Object value) throws Exce GeneratedAccess_com_codename1_health_workout.setStaticField(type, name, value); return; } + if ("com.codename1.home".equals(candidate)) { + GeneratedAccess_com_codename1_home.setStaticField(type, name, value); + return; + } + if ("com.codename1.home.commissioning".equals(candidate)) { + GeneratedAccess_com_codename1_home_commissioning.setStaticField(type, name, value); + return; + } + if ("com.codename1.home.spi".equals(candidate)) { + GeneratedAccess_com_codename1_home_spi.setStaticField(type, name, value); + return; + } + if ("com.codename1.intents".equals(candidate)) { + GeneratedAccess_com_codename1_intents.setStaticField(type, name, value); + return; + } + if ("com.codename1.intents.spi".equals(candidate)) { + GeneratedAccess_com_codename1_intents_spi.setStaticField(type, name, value); + return; + } if ("com.codename1.io".equals(candidate)) { GeneratedAccess_com_codename1_io.setStaticField(type, name, value); return; @@ -9358,6 +9847,10 @@ public void setStaticField(Class type, String name, Object value) throws Exce GeneratedAccess_com_codename1_security.setStaticField(type, name, value); return; } + if ("com.codename1.security.hardening".equals(candidate)) { + GeneratedAccess_com_codename1_security_hardening.setStaticField(type, name, value); + return; + } if ("com.codename1.security.shield".equals(candidate)) { GeneratedAccess_com_codename1_security_shield.setStaticField(type, name, value); return; @@ -9619,6 +10112,12 @@ public void setField(Object target, String name, Object value) throws Exception } catch (CN1AccessException ex) { unsupported = ex; } + try { + GeneratedAccess_com_codename1_annotations_buildhints.setField(target, name, value); + return; + } catch (CN1AccessException ex) { + unsupported = ex; + } try { GeneratedAccess_com_codename1_annotations_graphql.setField(target, name, value); return; @@ -9937,6 +10436,36 @@ public void setField(Object target, String name, Object value) throws Exception } catch (CN1AccessException ex) { unsupported = ex; } + try { + GeneratedAccess_com_codename1_home.setField(target, name, value); + return; + } catch (CN1AccessException ex) { + unsupported = ex; + } + try { + GeneratedAccess_com_codename1_home_commissioning.setField(target, name, value); + return; + } catch (CN1AccessException ex) { + unsupported = ex; + } + try { + GeneratedAccess_com_codename1_home_spi.setField(target, name, value); + return; + } catch (CN1AccessException ex) { + unsupported = ex; + } + try { + GeneratedAccess_com_codename1_intents.setField(target, name, value); + return; + } catch (CN1AccessException ex) { + unsupported = ex; + } + try { + GeneratedAccess_com_codename1_intents_spi.setField(target, name, value); + return; + } catch (CN1AccessException ex) { + unsupported = ex; + } try { GeneratedAccess_com_codename1_io.setField(target, name, value); return; @@ -10159,6 +10688,12 @@ public void setField(Object target, String name, Object value) throws Exception } catch (CN1AccessException ex) { unsupported = ex; } + try { + GeneratedAccess_com_codename1_security_hardening.setField(target, name, value); + return; + } catch (CN1AccessException ex) { + unsupported = ex; + } try { GeneratedAccess_com_codename1_security_shield.setField(target, name, value); return; diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ai_vision.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ai_vision.java index 52998b9d85e..955ec85683d 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ai_vision.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ai_vision.java @@ -55,9 +55,18 @@ private static Class findClassChunk0(String simpleName) { if ("Barcode".equals(simpleName)) { return com.codename1.ai.vision.Barcode.class; } + if ("BarcodeFormat".equals(simpleName)) { + return com.codename1.ai.vision.BarcodeFormat.class; + } if ("BarcodeScanner".equals(simpleName)) { return com.codename1.ai.vision.BarcodeScanner.class; } + if ("CodeScanner".equals(simpleName)) { + return com.codename1.ai.vision.CodeScanner.class; + } + if ("CodeScannerOptions".equals(simpleName)) { + return com.codename1.ai.vision.CodeScannerOptions.class; + } if ("DocumentScanResult".equals(simpleName)) { return com.codename1.ai.vision.DocumentScanResult.class; } @@ -70,6 +79,9 @@ private static Class findClassChunk0(String simpleName) { if ("FaceDetector".equals(simpleName)) { return com.codename1.ai.vision.FaceDetector.class; } + if ("FaceLandmarks".equals(simpleName)) { + return com.codename1.ai.vision.FaceLandmarks.class; + } if ("ImageLabel".equals(simpleName)) { return com.codename1.ai.vision.ImageLabel.class; } @@ -85,6 +97,9 @@ private static Class findClassChunk0(String simpleName) { if ("PoseDetector".equals(simpleName)) { return com.codename1.ai.vision.PoseDetector.class; } + if ("PoseLandmarks".equals(simpleName)) { + return com.codename1.ai.vision.PoseLandmarks.class; + } if ("SegmentationMask".equals(simpleName)) { return com.codename1.ai.vision.SegmentationMask.class; } @@ -100,6 +115,9 @@ private static Class findClassChunk0(String simpleName) { if ("TextRecognizer".equals(simpleName)) { return com.codename1.ai.vision.TextRecognizer.class; } + if ("TextScript".equals(simpleName)) { + return com.codename1.ai.vision.TextScript.class; + } if ("VisionAnalyzer".equals(simpleName)) { return com.codename1.ai.vision.VisionAnalyzer.class; } @@ -109,6 +127,9 @@ private static Class findClassChunk0(String simpleName) { if ("VisionBackends".equals(simpleName)) { return com.codename1.ai.vision.VisionBackends.class; } + if ("VisionCameraView".equals(simpleName)) { + return com.codename1.ai.vision.VisionCameraView.class; + } if ("VisionException".equals(simpleName)) { return com.codename1.ai.vision.VisionException.class; } @@ -160,6 +181,12 @@ public static Object construct(Class type, Object[] args) throws Exception { return new com.codename1.ai.vision.BarcodeScanner((com.codename1.ai.vision.VisionOptions) adaptedArgs[0]); } } + if (type == com.codename1.ai.vision.CodeScannerOptions.class) { + if (matches(safeArgs, new Class[0], false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[0], false); + return new com.codename1.ai.vision.CodeScannerOptions(); + } + } if (type == com.codename1.ai.vision.DocumentScanResult.class) { if (matches(safeArgs, new Class[]{byte[][].class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{byte[][].class}, false); @@ -292,6 +319,12 @@ public static Object construct(Class type, Object[] args) throws Exception { return new com.codename1.ai.vision.TextRecognizer((com.codename1.ai.vision.VisionOptions) adaptedArgs[0]); } } + if (type == com.codename1.ai.vision.VisionCameraView.class) { + if (matches(safeArgs, new Class[]{com.codename1.ai.vision.VisionAnalyzer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ai.vision.VisionAnalyzer.class}, false); + return new com.codename1.ai.vision.VisionCameraView((com.codename1.ai.vision.VisionAnalyzer) adaptedArgs[0]); + } + } if (type == com.codename1.ai.vision.VisionException.class) { if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class}, false); @@ -341,12 +374,76 @@ public static Object construct(Class type, Object[] args) throws Exception { public static Object invokeStatic(Class type, String name, Object[] args) throws Exception { Object[] safeArgs = safeArgs(args); - if (type == com.codename1.ai.vision.VisionBackends.class) return invokeStatic0(name, safeArgs); - if (type == com.codename1.ai.vision.VisionImage.class) return invokeStatic1(name, safeArgs); + if (type == com.codename1.ai.vision.BarcodeFormat.class) return invokeStatic0(name, safeArgs); + if (type == com.codename1.ai.vision.CodeScanner.class) return invokeStatic1(name, safeArgs); + if (type == com.codename1.ai.vision.TextScript.class) return invokeStatic2(name, safeArgs); + if (type == com.codename1.ai.vision.VisionBackends.class) return invokeStatic3(name, safeArgs); + if (type == com.codename1.ai.vision.VisionImage.class) return invokeStatic4(name, safeArgs); throw unsupportedStatic(type, name, safeArgs); } private static Object invokeStatic0(String name, Object[] safeArgs) throws Exception { + if ("matches".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ai.vision.Barcode.class, java.lang.String[].class}, true)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ai.vision.Barcode.class, java.lang.String[].class}, true); + java.lang.String[] varArgs = new java.lang.String[adaptedArgs.length - 1]; + for (int i = 1; i < adaptedArgs.length; i++) { + varArgs[i - 1] = (java.lang.String) adaptedArgs[i]; + } + return com.codename1.ai.vision.BarcodeFormat.matches((com.codename1.ai.vision.Barcode) adaptedArgs[0], varArgs); + } + } + throw unsupportedStatic(com.codename1.ai.vision.BarcodeFormat.class, name, safeArgs); + } + + private static Object invokeStatic1(String name, Object[] safeArgs) throws Exception { + if ("isSupported".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.ai.vision.CodeScanner.isSupported(); + } + } + if ("scan".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.ai.vision.CodeScanner.scan(); + } + if (matches(safeArgs, new Class[]{com.codename1.ai.vision.CodeScannerOptions.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ai.vision.CodeScannerOptions.class}, false); + return com.codename1.ai.vision.CodeScanner.scan((com.codename1.ai.vision.CodeScannerOptions) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.ai.vision.CodeScanner.class, name, safeArgs); + } + + private static Object invokeStatic2(String name, Object[] safeArgs) throws Exception { + if ("chinese".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.ai.vision.TextScript.chinese(); + } + } + if ("devanagari".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.ai.vision.TextScript.devanagari(); + } + } + if ("japanese".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.ai.vision.TextScript.japanese(); + } + } + if ("korean".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.ai.vision.TextScript.korean(); + } + } + if ("latin".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.ai.vision.TextScript.latin(); + } + } + throw unsupportedStatic(com.codename1.ai.vision.TextScript.class, name, safeArgs); + } + + private static Object invokeStatic3(String name, Object[] safeArgs) throws Exception { if ("appleVision".equals(name)) { if (safeArgs.length == 0) { return com.codename1.ai.vision.VisionBackends.appleVision(); @@ -390,7 +487,7 @@ private static Object invokeStatic0(String name, Object[] safeArgs) throws Excep throw unsupportedStatic(com.codename1.ai.vision.VisionBackends.class, name, safeArgs); } - private static Object invokeStatic1(String name, Object[] safeArgs) throws Exception { + private static Object invokeStatic4(String name, Object[] safeArgs) throws Exception { if ("encoded".equals(name)) { if (matches(safeArgs, new Class[]{byte[].class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{byte[].class}, false); @@ -407,6 +504,18 @@ private static Object invokeStatic1(String name, Object[] safeArgs) throws Excep return com.codename1.ai.vision.VisionImage.fromCameraFrame((com.codename1.camera.CameraFrame) adaptedArgs[0]); } } + if ("fromFile".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.ai.vision.VisionImage.fromFile((java.lang.String) adaptedArgs[0]); + } + } + if ("fromImage".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Image.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Image.class}, false); + return com.codename1.ai.vision.VisionImage.fromImage((com.codename1.ui.Image) adaptedArgs[0]); + } + } if ("pixels".equals(name)) { if (matches(safeArgs, new Class[]{byte[].class, java.lang.Integer.class, java.lang.Integer.class, com.codename1.camera.FrameFormat.class, java.lang.Integer.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{byte[].class, java.lang.Integer.class, java.lang.Integer.class, com.codename1.camera.FrameFormat.class, java.lang.Integer.class}, false); @@ -426,128 +535,149 @@ public static Object invoke(Object target, String name, Object[] args) throws Ex unsupported = ex; } } + if (target instanceof com.codename1.ai.vision.CodeScannerOptions) { + try { + return invoke1((com.codename1.ai.vision.CodeScannerOptions) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } if (target instanceof com.codename1.ai.vision.DocumentScanResult) { try { - return invoke1((com.codename1.ai.vision.DocumentScanResult) target, name, safeArgs); + return invoke2((com.codename1.ai.vision.DocumentScanResult) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.Face) { try { - return invoke2((com.codename1.ai.vision.Face) target, name, safeArgs); + return invoke3((com.codename1.ai.vision.Face) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.ImageLabel) { try { - return invoke3((com.codename1.ai.vision.ImageLabel) target, name, safeArgs); + return invoke4((com.codename1.ai.vision.ImageLabel) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.Pose) { try { - return invoke4((com.codename1.ai.vision.Pose) target, name, safeArgs); + return invoke5((com.codename1.ai.vision.Pose) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.Pose.Landmark) { try { - return invoke5((com.codename1.ai.vision.Pose.Landmark) target, name, safeArgs); + return invoke6((com.codename1.ai.vision.Pose.Landmark) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.SegmentationMask) { try { - return invoke6((com.codename1.ai.vision.SegmentationMask) target, name, safeArgs); + return invoke7((com.codename1.ai.vision.SegmentationMask) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.TextRecognitionResult) { try { - return invoke7((com.codename1.ai.vision.TextRecognitionResult) target, name, safeArgs); + return invoke8((com.codename1.ai.vision.TextRecognitionResult) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.TextRecognitionResult.TextBlock) { try { - return invoke8((com.codename1.ai.vision.TextRecognitionResult.TextBlock) target, name, safeArgs); + return invoke9((com.codename1.ai.vision.TextRecognitionResult.TextBlock) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.ai.vision.TextScript) { + try { + return invoke10((com.codename1.ai.vision.TextScript) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.ai.vision.VisionCameraView) { + try { + return invoke11((com.codename1.ai.vision.VisionCameraView) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.VisionException) { try { - return invoke9((com.codename1.ai.vision.VisionException) target, name, safeArgs); + return invoke12((com.codename1.ai.vision.VisionException) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.VisionImage) { try { - return invoke10((com.codename1.ai.vision.VisionImage) target, name, safeArgs); + return invoke13((com.codename1.ai.vision.VisionImage) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.VisionMetadata) { try { - return invoke11((com.codename1.ai.vision.VisionMetadata) target, name, safeArgs); + return invoke14((com.codename1.ai.vision.VisionMetadata) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.VisionOptions) { try { - return invoke12((com.codename1.ai.vision.VisionOptions) target, name, safeArgs); + return invoke15((com.codename1.ai.vision.VisionOptions) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.VisionPipeline) { try { - return invoke13((com.codename1.ai.vision.VisionPipeline) target, name, safeArgs); + return invoke16((com.codename1.ai.vision.VisionPipeline) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.VisionPoint) { try { - return invoke14((com.codename1.ai.vision.VisionPoint) target, name, safeArgs); + return invoke17((com.codename1.ai.vision.VisionPoint) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.VisionRect) { try { - return invoke15((com.codename1.ai.vision.VisionRect) target, name, safeArgs); + return invoke18((com.codename1.ai.vision.VisionRect) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.VisionAnalyzer) { try { - return invoke16((com.codename1.ai.vision.VisionAnalyzer) target, name, safeArgs); + return invoke19((com.codename1.ai.vision.VisionAnalyzer) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.VisionBackend) { try { - return invoke17((com.codename1.ai.vision.VisionBackend) target, name, safeArgs); + return invoke20((com.codename1.ai.vision.VisionBackend) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.ai.vision.VisionPipelineListener) { try { - return invoke18((com.codename1.ai.vision.VisionPipelineListener) target, name, safeArgs); + return invoke21((com.codename1.ai.vision.VisionPipelineListener) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } @@ -592,7 +722,81 @@ private static Object invoke0(com.codename1.ai.vision.Barcode typedTarget, Strin throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke1(com.codename1.ai.vision.DocumentScanResult typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke1(com.codename1.ai.vision.CodeScannerOptions typedTarget, String name, Object[] safeArgs) throws Exception { + if ("facing".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.camera.CameraFacing.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.camera.CameraFacing.class}, false); + return typedTarget.facing((com.codename1.camera.CameraFacing) adaptedArgs[0]); + } + } + if ("formats".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String[].class}, true)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String[].class}, true); + java.lang.String[] varArgs = new java.lang.String[adaptedArgs.length - 0]; + for (int i = 0; i < adaptedArgs.length; i++) { + varArgs[i - 0] = (java.lang.String) adaptedArgs[i]; + } + return typedTarget.formats(varArgs); + } + } + if ("getFacing".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getFacing(); + } + } + if ("getFormats".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getFormats(); + } + } + if ("getHint".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getHint(); + } + } + if ("getTitle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTitle(); + } + } + if ("getVisionOptions".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getVisionOptions(); + } + } + if ("hint".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.hint((java.lang.String) adaptedArgs[0]); + } + } + if ("isTorchButton".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isTorchButton(); + } + } + if ("title".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.title((java.lang.String) adaptedArgs[0]); + } + } + if ("torchButton".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + return typedTarget.torchButton(((Boolean) adaptedArgs[0]).booleanValue()); + } + } + if ("visionOptions".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ai.vision.VisionOptions.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ai.vision.VisionOptions.class}, false); + return typedTarget.visionOptions((com.codename1.ai.vision.VisionOptions) adaptedArgs[0]); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke2(com.codename1.ai.vision.DocumentScanResult typedTarget, String name, Object[] safeArgs) throws Exception { if ("getMetadata".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getMetadata(); @@ -612,12 +816,18 @@ private static Object invoke1(com.codename1.ai.vision.DocumentScanResult typedTa throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke2(com.codename1.ai.vision.Face typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke3(com.codename1.ai.vision.Face typedTarget, String name, Object[] safeArgs) throws Exception { if ("getBounds".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getBounds(); } } + if ("getLandmark".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getLandmark((java.lang.String) adaptedArgs[0]); + } + } if ("getLandmarks".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getLandmarks(); @@ -656,7 +866,7 @@ private static Object invoke2(com.codename1.ai.vision.Face typedTarget, String n throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke3(com.codename1.ai.vision.ImageLabel typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke4(com.codename1.ai.vision.ImageLabel typedTarget, String name, Object[] safeArgs) throws Exception { if ("getConfidence".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getConfidence(); @@ -680,7 +890,13 @@ private static Object invoke3(com.codename1.ai.vision.ImageLabel typedTarget, St throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke4(com.codename1.ai.vision.Pose typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke5(com.codename1.ai.vision.Pose typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getLandmark".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getLandmark((java.lang.String) adaptedArgs[0]); + } + } if ("getLandmarks".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getLandmarks(); @@ -694,7 +910,7 @@ private static Object invoke4(com.codename1.ai.vision.Pose typedTarget, String n throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke5(com.codename1.ai.vision.Pose.Landmark typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke6(com.codename1.ai.vision.Pose.Landmark typedTarget, String name, Object[] safeArgs) throws Exception { if ("getConfidence".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getConfidence(); @@ -713,12 +929,24 @@ private static Object invoke5(com.codename1.ai.vision.Pose.Landmark typedTarget, throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke6(com.codename1.ai.vision.SegmentationMask typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke7(com.codename1.ai.vision.SegmentationMask typedTarget, String name, Object[] safeArgs) throws Exception { + if ("cutOut".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Image.class, java.lang.Float.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Image.class, java.lang.Float.class}, false); + return typedTarget.cutOut((com.codename1.ui.Image) adaptedArgs[0], ((Number) adaptedArgs[1]).floatValue()); + } + } if ("getConfidence".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getConfidence(); } } + if ("getConfidenceAt".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.getConfidenceAt(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } if ("getHeight".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getHeight(); @@ -734,10 +962,16 @@ private static Object invoke6(com.codename1.ai.vision.SegmentationMask typedTarg return typedTarget.getWidth(); } } + if ("toMaskImage".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return typedTarget.toMaskImage(toIntValue(adaptedArgs[0])); + } + } throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke7(com.codename1.ai.vision.TextRecognitionResult typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke8(com.codename1.ai.vision.TextRecognitionResult typedTarget, String name, Object[] safeArgs) throws Exception { if ("getBlocks".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getBlocks(); @@ -756,7 +990,7 @@ private static Object invoke7(com.codename1.ai.vision.TextRecognitionResult type throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke8(com.codename1.ai.vision.TextRecognitionResult.TextBlock typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke9(com.codename1.ai.vision.TextRecognitionResult.TextBlock typedTarget, String name, Object[] safeArgs) throws Exception { if ("getBounds".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getBounds(); @@ -780,186 +1014,2291 @@ private static Object invoke8(com.codename1.ai.vision.TextRecognitionResult.Text throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke9(com.codename1.ai.vision.VisionException typedTarget, String name, Object[] safeArgs) throws Exception { - if ("getCode".equals(name)) { + private static Object invoke10(com.codename1.ai.vision.TextScript typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getId".equals(name)) { if (safeArgs.length == 0) { - return typedTarget.getCode(); + return typedTarget.getId(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); } } throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke10(com.codename1.ai.vision.VisionImage typedTarget, String name, Object[] safeArgs) throws Exception { - if ("getEncodedBytes".equals(name)) { + private static Object invoke11(com.codename1.ai.vision.VisionCameraView typedTarget, String name, Object[] safeArgs) throws Exception { + if ("accessibilityChanged".equals(name)) { if (safeArgs.length == 0) { - return typedTarget.getEncodedBytes(); + typedTarget.accessibilityChanged(); return null; + } + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.accessibilityChanged(toIntValue(adaptedArgs[0])); return null; } } - if ("getEncodedBytesUnsafe".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getEncodedBytesUnsafe(); + if ("add".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + return typedTarget.add((com.codename1.ui.Component) adaptedArgs[0]); + } + if (matches(safeArgs, new Class[]{com.codename1.ui.Image.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Image.class}, false); + return typedTarget.add((com.codename1.ui.Image) adaptedArgs[0]); + } + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.add((java.lang.String) adaptedArgs[0]); + } + if (matches(safeArgs, new Class[]{java.lang.Object.class, com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Object.class, com.codename1.ui.Component.class}, false); + return typedTarget.add((java.lang.Object) adaptedArgs[0], (com.codename1.ui.Component) adaptedArgs[1]); + } + if (matches(safeArgs, new Class[]{java.lang.Object.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Object.class, java.lang.String.class}, false); + return typedTarget.add((java.lang.Object) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); + } + if (matches(safeArgs, new Class[]{java.lang.Object.class, com.codename1.ui.Image.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Object.class, com.codename1.ui.Image.class}, false); + return typedTarget.add((java.lang.Object) adaptedArgs[0], (com.codename1.ui.Image) adaptedArgs[1]); } } - if ("getFormat".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getFormat(); + if ("addAll".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component[].class}, true)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component[].class}, true); + com.codename1.ui.Component[] varArgs = new com.codename1.ui.Component[adaptedArgs.length - 0]; + for (int i = 0; i < adaptedArgs.length; i++) { + varArgs[i - 0] = (com.codename1.ui.Component) adaptedArgs[i]; + } + return typedTarget.addAll(varArgs); } } - if ("getHeight".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getHeight(); + if ("addComponent".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + typedTarget.addComponent((com.codename1.ui.Component) adaptedArgs[0]); return null; + } + if (matches(safeArgs, new Class[]{java.lang.Integer.class, com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, com.codename1.ui.Component.class}, false); + typedTarget.addComponent(toIntValue(adaptedArgs[0]), (com.codename1.ui.Component) adaptedArgs[1]); return null; + } + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Object.class, com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Object.class, com.codename1.ui.Component.class}, false); + typedTarget.addComponent(toIntValue(adaptedArgs[0]), (java.lang.Object) adaptedArgs[1], (com.codename1.ui.Component) adaptedArgs[2]); return null; } } - if ("getPixels".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getPixels(); + if ("addContextMenuListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addContextMenuListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } - if ("getPixelsUnsafe".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getPixelsUnsafe(); + if ("addDragFinishedListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addDragFinishedListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } - if ("getRotationDegrees".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getRotationDegrees(); + if ("addDragOverListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addDragOverListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } - if ("getTimestampNanos".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getTimestampNanos(); + if ("addDropListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addDropListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } - if ("getWidth".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getWidth(); + if ("addFocusListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.FocusListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.FocusListener.class}, false); + typedTarget.addFocusListener((com.codename1.ui.events.FocusListener) adaptedArgs[0]); return null; } } - throw unsupportedInstance(typedTarget, name, safeArgs); - } - - private static Object invoke11(com.codename1.ai.vision.VisionMetadata typedTarget, String name, Object[] safeArgs) throws Exception { - if ("get".equals(name)) { - if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { - Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); - return typedTarget.get((java.lang.String) adaptedArgs[0]); + if ("addLongPressListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addLongPressListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } - if ("getBackendId".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getBackendId(); + if ("addMouseWheelListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addMouseWheelListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } - if ("getValues".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getValues(); + if ("addPointerDraggedListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addPointerDraggedListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } - throw unsupportedInstance(typedTarget, name, safeArgs); - } - - private static Object invoke12(com.codename1.ai.vision.VisionOptions typedTarget, String name, Object[] safeArgs) throws Exception { - if ("backend".equals(name)) { - if (matches(safeArgs, new Class[]{com.codename1.ai.vision.VisionBackend.class}, false)) { - Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ai.vision.VisionBackend.class}, false); - return typedTarget.backend((com.codename1.ai.vision.VisionBackend) adaptedArgs[0]); + if ("addPointerPressedListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addPointerPressedListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } - if ("getBackend".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getBackend(); + if ("addPointerReleasedListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addPointerReleasedListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } - if ("getMaximumResults".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getMaximumResults(); + if ("addPullToRefresh".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Runnable.class}, false); + typedTarget.addPullToRefresh((java.lang.Runnable) adaptedArgs[0]); return null; } } - if ("getMinimumConfidence".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getMinimumConfidence(); + if ("addScrollListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ScrollListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ScrollListener.class}, false); + typedTarget.addScrollListener((com.codename1.ui.events.ScrollListener) adaptedArgs[0]); return null; } } - if ("maximumResults".equals(name)) { - if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { - Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); - return typedTarget.maximumResults(toIntValue(adaptedArgs[0])); + if ("addStateChangeListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addStateChangeListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } - if ("minimumConfidence".equals(name)) { - if (matches(safeArgs, new Class[]{java.lang.Float.class}, false)) { - Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Float.class}, false); - return typedTarget.minimumConfidence(((Number) adaptedArgs[0]).floatValue()); + if ("addStylusListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addStylusListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } - throw unsupportedInstance(typedTarget, name, safeArgs); - } - - private static Object invoke13(com.codename1.ai.vision.VisionPipeline typedTarget, String name, Object[] safeArgs) throws Exception { - if ("close".equals(name)) { + if ("animate".equals(name)) { if (safeArgs.length == 0) { - typedTarget.close(); return null; + return typedTarget.animate(); } } - if ("isBusy".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.isBusy(); + if ("animateHierarchy".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.animateHierarchy(toIntValue(adaptedArgs[0])); return null; } } - throw unsupportedInstance(typedTarget, name, safeArgs); - } - - private static Object invoke14(com.codename1.ai.vision.VisionPoint typedTarget, String name, Object[] safeArgs) throws Exception { - if ("getX".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getX(); + if ("animateHierarchyAndWait".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.animateHierarchyAndWait(toIntValue(adaptedArgs[0])); return null; } } - if ("getY".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getY(); + if ("animateHierarchyFade".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.animateHierarchyFade(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); return null; } } - throw unsupportedInstance(typedTarget, name, safeArgs); - } - - private static Object invoke15(com.codename1.ai.vision.VisionRect typedTarget, String name, Object[] safeArgs) throws Exception { - if ("getHeight".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getHeight(); + if ("animateHierarchyFadeAndWait".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.animateHierarchyFadeAndWait(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); return null; } } - if ("getWidth".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getWidth(); + if ("animateLayout".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.animateLayout(toIntValue(adaptedArgs[0])); return null; } } - if ("getX".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getX(); + if ("animateLayoutAndWait".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.animateLayoutAndWait(toIntValue(adaptedArgs[0])); return null; } } - if ("getY".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.getY(); + if ("animateLayoutFade".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.animateLayoutFade(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); return null; } } - throw unsupportedInstance(typedTarget, name, safeArgs); - } - - private static Object invoke16(com.codename1.ai.vision.VisionAnalyzer typedTarget, String name, Object[] safeArgs) throws Exception { - if ("close".equals(name)) { - if (safeArgs.length == 0) { - typedTarget.close(); return null; + if ("animateLayoutFadeAndWait".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.animateLayoutFadeAndWait(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); return null; } } - if ("isSupported".equals(name)) { - if (safeArgs.length == 0) { - return typedTarget.isSupported(); + if ("animateUnlayout".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Runnable.class}, false); + typedTarget.animateUnlayout(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1]), (java.lang.Runnable) adaptedArgs[2]); return null; } } - if ("process".equals(name)) { - if (matches(safeArgs, new Class[]{com.codename1.ai.vision.VisionImage.class}, false)) { + if ("animateUnlayoutAndWait".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.animateUnlayoutAndWait(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); return null; + } + } + if ("announceForAccessibility".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.announceForAccessibility((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("applyRTL".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.applyRTL(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("bindProperty".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, com.codename1.cloud.BindTarget.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, com.codename1.cloud.BindTarget.class}, false); + typedTarget.bindProperty((java.lang.String) adaptedArgs[0], (com.codename1.cloud.BindTarget) adaptedArgs[1]); return null; + } + } + if ("blocksSideSwipe".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.blocksSideSwipe(); + } + } + if ("clearClientProperties".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.clearClientProperties(); return null; + } + } + if ("close".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.close(); return null; + } + } + if ("contains".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + return typedTarget.contains((com.codename1.ui.Component) adaptedArgs[0]); + } + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.contains(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } + if ("containsOrOwns".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.containsOrOwns(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } + if ("createAnimateHierarchy".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return typedTarget.createAnimateHierarchy(toIntValue(adaptedArgs[0])); + } + } + if ("createAnimateHierarchyFade".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.createAnimateHierarchyFade(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } + if ("createAnimateLayout".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return typedTarget.createAnimateLayout(toIntValue(adaptedArgs[0])); + } + } + if ("createAnimateLayoutFade".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.createAnimateLayoutFade(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } + if ("createAnimateLayoutFadeAndWait".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.createAnimateLayoutFadeAndWait(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } + if ("createAnimateUnlayout".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Runnable.class}, false); + return typedTarget.createAnimateUnlayout(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1]), (java.lang.Runnable) adaptedArgs[2]); + } + } + if ("createReplaceTransition".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class}, false); + return typedTarget.createReplaceTransition((com.codename1.ui.Component) adaptedArgs[0], (com.codename1.ui.Component) adaptedArgs[1], (com.codename1.ui.animations.Transition) adaptedArgs[2]); + } + } + if ("createStyleAnimation".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Integer.class}, false); + return typedTarget.createStyleAnimation((java.lang.String) adaptedArgs[0], toIntValue(adaptedArgs[1])); + } + } + if ("drop".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class, java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class, java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.drop((com.codename1.ui.Component) adaptedArgs[0], toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2])); return null; + } + } + if ("findDropTargetAt".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.findDropTargetAt(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } + if ("findFirstFocusable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.findFirstFocusable(); + } + } + if ("flushReplace".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.flushReplace(); return null; + } + } + if ("forceRevalidate".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.forceRevalidate(); return null; + } + } + if ("getAbsoluteX".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAbsoluteX(); + } + } + if ("getAbsoluteY".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAbsoluteY(); + } + } + if ("getAccessibilityNode".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessibilityNode(); + } + } + if ("getAccessibilityText".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessibilityText(); + } + } + if ("getAllStyles".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAllStyles(); + } + } + if ("getAnimationManager".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAnimationManager(); + } + } + if ("getBaseline".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.getBaseline(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } + if ("getBaselineResizeBehavior".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBaselineResizeBehavior(); + } + } + if ("getBindablePropertyNames".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBindablePropertyNames(); + } + } + if ("getBindablePropertyTypes".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBindablePropertyTypes(); + } + } + if ("getBottomGap".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBottomGap(); + } + } + if ("getBoundPropertyValue".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getBoundPropertyValue((java.lang.String) adaptedArgs[0]); + } + } + if ("getBounds".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.geom.Rectangle.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.geom.Rectangle.class}, false); + return typedTarget.getBounds((com.codename1.ui.geom.Rectangle) adaptedArgs[0]); + } + } + if ("getChildrenAsList".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + return typedTarget.getChildrenAsList(((Boolean) adaptedArgs[0]).booleanValue()); + } + } + if ("getClientProperty".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getClientProperty((java.lang.String) adaptedArgs[0]); + } + } + if ("getClosestComponentTo".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.getClosestComponentTo(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } + if ("getCloudBoundProperty".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getCloudBoundProperty(); + } + } + if ("getCloudDestinationProperty".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getCloudDestinationProperty(); + } + } + if ("getComponentAt".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return typedTarget.getComponentAt(toIntValue(adaptedArgs[0])); + } + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.getComponentAt(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } + if ("getComponentCount".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getComponentCount(); + } + } + if ("getComponentForm".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getComponentForm(); + } + } + if ("getComponentIndex".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + return typedTarget.getComponentIndex((com.codename1.ui.Component) adaptedArgs[0]); + } + } + if ("getComponentState".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getComponentState(); + } + } + if ("getCursor".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getCursor(); + } + } + if ("getDirtyRegion".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDirtyRegion(); + } + } + if ("getDisabledStyle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDisabledStyle(); + } + } + if ("getDragTransparency".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDragTransparency(); + } + } + if ("getDraggedx".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDraggedx(); + } + } + if ("getDraggedy".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDraggedy(); + } + } + if ("getEditingDelegate".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getEditingDelegate(); + } + } + if ("getFacing".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getFacing(); + } + } + if ("getHeight".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getHeight(); + } + } + if ("getInlineAllStyles".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInlineAllStyles(); + } + } + if ("getInlineDisabledStyles".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInlineDisabledStyles(); + } + } + if ("getInlinePressedStyles".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInlinePressedStyles(); + } + } + if ("getInlineSelectedStyles".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInlineSelectedStyles(); + } + } + if ("getInlineStylesTheme".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInlineStylesTheme(); + } + } + if ("getInlineUnselectedStyles".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInlineUnselectedStyles(); + } + } + if ("getInnerHeight".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInnerHeight(); + } + } + if ("getInnerPreferredH".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInnerPreferredH(); + } + } + if ("getInnerPreferredW".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInnerPreferredW(); + } + } + if ("getInnerWidth".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInnerWidth(); + } + } + if ("getInnerX".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInnerX(); + } + } + if ("getInnerY".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInnerY(); + } + } + if ("getLabelForComponent".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getLabelForComponent(); + } + } + if ("getLayout".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getLayout(); + } + } + if ("getLayoutHeight".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getLayoutHeight(); + } + } + if ("getLayoutWidth".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getLayoutWidth(); + } + } + if ("getLeadComponent".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getLeadComponent(); + } + } + if ("getLeadParent".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getLeadParent(); + } + } + if ("getListener".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getListener(); + } + } + if ("getMaxFps".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getMaxFps(); + } + } + if ("getName".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getName(); + } + } + if ("getNativeOverlay".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getNativeOverlay(); + } + } + if ("getNextFocusDown".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getNextFocusDown(); + } + } + if ("getNextFocusLeft".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getNextFocusLeft(); + } + } + if ("getNextFocusRight".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getNextFocusRight(); + } + } + if ("getNextFocusUp".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getNextFocusUp(); + } + } + if ("getOuterHeight".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getOuterHeight(); + } + } + if ("getOuterPreferredH".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getOuterPreferredH(); + } + } + if ("getOuterPreferredW".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getOuterPreferredW(); + } + } + if ("getOuterWidth".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getOuterWidth(); + } + } + if ("getOuterX".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getOuterX(); + } + } + if ("getOuterY".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getOuterY(); + } + } + if ("getOwner".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getOwner(); + } + } + if ("getParent".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getParent(); + } + } + if ("getPreferredH".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPreferredH(); + } + } + if ("getPreferredSize".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPreferredSize(); + } + } + if ("getPreferredSizeStr".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPreferredSizeStr(); + } + } + if ("getPreferredTabIndex".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPreferredTabIndex(); + } + } + if ("getPreferredW".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPreferredW(); + } + } + if ("getPressedStyle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPressedStyle(); + } + } + if ("getPropertyNames".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPropertyNames(); + } + } + if ("getPropertyTypeNames".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPropertyTypeNames(); + } + } + if ("getPropertyTypes".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPropertyTypes(); + } + } + if ("getPropertyValue".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getPropertyValue((java.lang.String) adaptedArgs[0]); + } + } + if ("getResponderAt".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.getResponderAt(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } + if ("getSafeAreaRoot".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSafeAreaRoot(); + } + } + if ("getSameHeight".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSameHeight(); + } + } + if ("getSameWidth".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSameWidth(); + } + } + if ("getScaleType".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getScaleType(); + } + } + if ("getScrollAnimationSpeed".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getScrollAnimationSpeed(); + } + } + if ("getScrollDimension".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getScrollDimension(); + } + } + if ("getScrollIncrement".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getScrollIncrement(); + } + } + if ("getScrollOpacity".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getScrollOpacity(); + } + } + if ("getScrollOpacityChangeSpeed".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getScrollOpacityChangeSpeed(); + } + } + if ("getScrollX".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getScrollX(); + } + } + if ("getScrollY".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getScrollY(); + } + } + if ("getScrollable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getScrollable(); + } + } + if ("getSelectCommandText".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSelectCommandText(); + } + } + if ("getSelectedRect".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSelectedRect(); + } + } + if ("getSelectedStyle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSelectedStyle(); + } + } + if ("getSemantics".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSemantics(); + } + } + if ("getSession".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSession(); + } + } + if ("getSideGap".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSideGap(); + } + } + if ("getStyle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getStyle(); + } + } + if ("getTabIndex".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTabIndex(); + } + } + if ("getTensileLength".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTensileLength(); + } + } + if ("getTextSelectionSupport".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTextSelectionSupport(); + } + } + if ("getTooltip".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTooltip(); + } + } + if ("getUIID".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getUIID(); + } + } + if ("getUIManager".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getUIManager(); + } + } + if ("getUnselectedStyle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getUnselectedStyle(); + } + } + if ("getVisibleBounds".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.geom.Rectangle.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.geom.Rectangle.class}, false); + return typedTarget.getVisibleBounds((com.codename1.ui.geom.Rectangle) adaptedArgs[0]); + } + } + if ("getWidth".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getWidth(); + } + } + if ("getX".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getX(); + } + } + if ("getY".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getY(); + } + } + if ("growShrink".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.growShrink(toIntValue(adaptedArgs[0])); return null; + } + } + if ("handlesInput".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.handlesInput(); + } + } + if ("hasFixedPreferredSize".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.hasFixedPreferredSize(); + } + } + if ("hasFocus".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.hasFocus(); + } + } + if ("invalidate".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.invalidate(); return null; + } + } + if ("isAlwaysTensile".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isAlwaysTensile(); + } + } + if ("isBlockLead".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isBlockLead(); + } + } + if ("isCellRenderer".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isCellRenderer(); + } + } + if ("isChildOf".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Container.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Container.class}, false); + return typedTarget.isChildOf((com.codename1.ui.Container) adaptedArgs[0]); + } + } + if ("isDraggable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isDraggable(); + } + } + if ("isDropTarget".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isDropTarget(); + } + } + if ("isEditable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isEditable(); + } + } + if ("isEditing".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isEditing(); + } + } + if ("isEnabled".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isEnabled(); + } + } + if ("isFlatten".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isFlatten(); + } + } + if ("isFocusable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isFocusable(); + } + } + if ("isGrabsPointerEvents".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isGrabsPointerEvents(); + } + } + if ("isHScrollThumbGrabbed".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isHScrollThumbGrabbed(); + } + } + if ("isHScrollThumbHover".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isHScrollThumbHover(); + } + } + if ("isHidden".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isHidden(); + } + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + return typedTarget.isHidden(((Boolean) adaptedArgs[0]).booleanValue()); + } + } + if ("isHideInLandscape".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isHideInLandscape(); + } + } + if ("isHideInPortrait".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isHideInPortrait(); + } + } + if ("isIgnorePointerEvents".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isIgnorePointerEvents(); + } + } + if ("isOpaque".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isOpaque(); + } + } + if ("isOwnedBy".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + return typedTarget.isOwnedBy((com.codename1.ui.Component) adaptedArgs[0]); + } + } + if ("isPinchBlocksDragAndDrop".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isPinchBlocksDragAndDrop(); + } + } + if ("isRTL".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isRTL(); + } + } + if ("isRippleEffect".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isRippleEffect(); + } + } + if ("isRunning".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isRunning(); + } + } + if ("isSafeArea".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isSafeArea(); + } + } + if ("isSafeAreaRoot".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isSafeAreaRoot(); + } + } + if ("isScrollVisible".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isScrollVisible(); + } + } + if ("isScrollableX".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isScrollableX(); + } + } + if ("isScrollableY".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isScrollableY(); + } + } + if ("isSmoothScrolling".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isSmoothScrolling(); + } + } + if ("isSnapToGrid".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isSnapToGrid(); + } + } + if ("isSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isSupported(); + } + } + if ("isSurface".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isSurface(); + } + } + if ("isTactileTouch".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isTactileTouch(); + } + } + if ("isTensileDragEnabled".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isTensileDragEnabled(); + } + } + if ("isTraversable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isTraversable(); + } + } + if ("isVScrollThumbGrabbed".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isVScrollThumbGrabbed(); + } + } + if ("isVScrollThumbHover".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isVScrollThumbHover(); + } + } + if ("isVisible".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isVisible(); + } + } + if ("iterator".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.iterator(); + } + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + return typedTarget.iterator(((Boolean) adaptedArgs[0]).booleanValue()); + } + } + if ("keyPressed".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.keyPressed(toIntValue(adaptedArgs[0])); return null; + } + } + if ("keyReleased".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.keyReleased(toIntValue(adaptedArgs[0])); return null; + } + } + if ("keyRepeated".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.keyRepeated(toIntValue(adaptedArgs[0])); return null; + } + } + if ("layoutContainer".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.layoutContainer(); return null; + } + } + if ("longPointerPress".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.longPointerPress(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); return null; + } + } + if ("morph".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, java.lang.Integer.class, java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, java.lang.Integer.class, java.lang.Runnable.class}, false); + typedTarget.morph((com.codename1.ui.Component) adaptedArgs[0], (com.codename1.ui.Component) adaptedArgs[1], toIntValue(adaptedArgs[2]), (java.lang.Runnable) adaptedArgs[3]); return null; + } + } + if ("morphAndWait".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, java.lang.Integer.class}, false); + typedTarget.morphAndWait((com.codename1.ui.Component) adaptedArgs[0], (com.codename1.ui.Component) adaptedArgs[1], toIntValue(adaptedArgs[2])); return null; + } + } + if ("paint".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Graphics.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Graphics.class}, false); + typedTarget.paint((com.codename1.ui.Graphics) adaptedArgs[0]); return null; + } + } + if ("paintBackgrounds".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Graphics.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Graphics.class}, false); + typedTarget.paintBackgrounds((com.codename1.ui.Graphics) adaptedArgs[0]); return null; + } + } + if ("paintComponent".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Graphics.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Graphics.class}, false); + typedTarget.paintComponent((com.codename1.ui.Graphics) adaptedArgs[0]); return null; + } + if (matches(safeArgs, new Class[]{com.codename1.ui.Graphics.class, java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Graphics.class, java.lang.Boolean.class}, false); + typedTarget.paintComponent((com.codename1.ui.Graphics) adaptedArgs[0], ((Boolean) adaptedArgs[1]).booleanValue()); return null; + } + } + if ("paintComponentBackground".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Graphics.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Graphics.class}, false); + typedTarget.paintComponentBackground((com.codename1.ui.Graphics) adaptedArgs[0]); return null; + } + } + if ("paintIntersectingComponentsAbove".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Graphics.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Graphics.class}, false); + typedTarget.paintIntersectingComponentsAbove((com.codename1.ui.Graphics) adaptedArgs[0]); return null; + } + } + if ("paintLock".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + return typedTarget.paintLock(((Boolean) adaptedArgs[0]).booleanValue()); + } + } + if ("paintLockRelease".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.paintLockRelease(); return null; + } + } + if ("paintRippleOverlay".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Graphics.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Graphics.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.paintRippleOverlay((com.codename1.ui.Graphics) adaptedArgs[0], toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2]), toIntValue(adaptedArgs[3])); return null; + } + } + if ("paintShadows".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Graphics.class, java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Graphics.class, java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.paintShadows((com.codename1.ui.Graphics) adaptedArgs[0], toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2])); return null; + } + } + if ("pointerDragged".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.pointerDragged(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); return null; + } + if (matches(safeArgs, new Class[]{int[].class, int[].class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{int[].class, int[].class}, false); + typedTarget.pointerDragged((int[]) adaptedArgs[0], (int[]) adaptedArgs[1]); return null; + } + } + if ("pointerHover".equals(name)) { + if (matches(safeArgs, new Class[]{int[].class, int[].class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{int[].class, int[].class}, false); + typedTarget.pointerHover((int[]) adaptedArgs[0], (int[]) adaptedArgs[1]); return null; + } + } + if ("pointerHoverPressed".equals(name)) { + if (matches(safeArgs, new Class[]{int[].class, int[].class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{int[].class, int[].class}, false); + typedTarget.pointerHoverPressed((int[]) adaptedArgs[0], (int[]) adaptedArgs[1]); return null; + } + } + if ("pointerHoverReleased".equals(name)) { + if (matches(safeArgs, new Class[]{int[].class, int[].class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{int[].class, int[].class}, false); + typedTarget.pointerHoverReleased((int[]) adaptedArgs[0], (int[]) adaptedArgs[1]); return null; + } + } + if ("pointerPressed".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.pointerPressed(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); return null; + } + if (matches(safeArgs, new Class[]{int[].class, int[].class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{int[].class, int[].class}, false); + typedTarget.pointerPressed((int[]) adaptedArgs[0], (int[]) adaptedArgs[1]); return null; + } + } + if ("pointerReleased".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.pointerReleased(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); return null; + } + if (matches(safeArgs, new Class[]{int[].class, int[].class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{int[].class, int[].class}, false); + typedTarget.pointerReleased((int[]) adaptedArgs[0], (int[]) adaptedArgs[1]); return null; + } + } + if ("putClientProperty".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Object.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Object.class}, false); + typedTarget.putClientProperty((java.lang.String) adaptedArgs[0], (java.lang.Object) adaptedArgs[1]); return null; + } + } + if ("refreshTheme".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.refreshTheme(); return null; + } + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.refreshTheme(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("remove".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.remove(); return null; + } + } + if ("removeAll".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.removeAll(); return null; + } + } + if ("removeComponent".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + typedTarget.removeComponent((com.codename1.ui.Component) adaptedArgs[0]); return null; + } + } + if ("removeContextMenuListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removeContextMenuListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } + if ("removeDragFinishedListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removeDragFinishedListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } + if ("removeDragOverListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removeDragOverListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } + if ("removeDropListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removeDropListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } + if ("removeFocusListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.FocusListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.FocusListener.class}, false); + typedTarget.removeFocusListener((com.codename1.ui.events.FocusListener) adaptedArgs[0]); return null; + } + } + if ("removeLongPressListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removeLongPressListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } + if ("removeMouseWheelListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removeMouseWheelListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } + if ("removePointerDraggedListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removePointerDraggedListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } + if ("removePointerPressedListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removePointerPressedListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } + if ("removePointerReleasedListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removePointerReleasedListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } + if ("removeScrollListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ScrollListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ScrollListener.class}, false); + typedTarget.removeScrollListener((com.codename1.ui.events.ScrollListener) adaptedArgs[0]); return null; + } + } + if ("removeStateChangeListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removeStateChangeListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } + if ("removeStylusListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removeStylusListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } + if ("repaint".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.repaint(); return null; + } + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.repaint(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2]), toIntValue(adaptedArgs[3])); return null; + } + } + if ("replace".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class}, false); + typedTarget.replace((com.codename1.ui.Component) adaptedArgs[0], (com.codename1.ui.Component) adaptedArgs[1], (com.codename1.ui.animations.Transition) adaptedArgs[2]); return null; + } + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class, java.lang.Runnable.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class, java.lang.Runnable.class, java.lang.Integer.class}, false); + typedTarget.replace((com.codename1.ui.Component) adaptedArgs[0], (com.codename1.ui.Component) adaptedArgs[1], (com.codename1.ui.animations.Transition) adaptedArgs[2], (java.lang.Runnable) adaptedArgs[3], toIntValue(adaptedArgs[4])); return null; + } + } + if ("replaceAndWait".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class}, false); + typedTarget.replaceAndWait((com.codename1.ui.Component) adaptedArgs[0], (com.codename1.ui.Component) adaptedArgs[1], (com.codename1.ui.animations.Transition) adaptedArgs[2]); return null; + } + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class, java.lang.Integer.class}, false); + typedTarget.replaceAndWait((com.codename1.ui.Component) adaptedArgs[0], (com.codename1.ui.Component) adaptedArgs[1], (com.codename1.ui.animations.Transition) adaptedArgs[2], toIntValue(adaptedArgs[3])); return null; + } + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class, java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class, com.codename1.ui.Component.class, com.codename1.ui.animations.Transition.class, java.lang.Boolean.class}, false); + typedTarget.replaceAndWait((com.codename1.ui.Component) adaptedArgs[0], (com.codename1.ui.Component) adaptedArgs[1], (com.codename1.ui.animations.Transition) adaptedArgs[2], ((Boolean) adaptedArgs[3]).booleanValue()); return null; + } + } + if ("requestFocus".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.requestFocus(); return null; + } + } + if ("respondsToPointerEvents".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.respondsToPointerEvents(); + } + } + if ("revalidate".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.revalidate(); return null; + } + } + if ("revalidateLater".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.revalidateLater(); return null; + } + } + if ("revalidateWithAnimationSafety".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.revalidateWithAnimationSafety(); return null; + } + } + if ("scrollComponentToVisible".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + typedTarget.scrollComponentToVisible((com.codename1.ui.Component) adaptedArgs[0]); return null; + } + } + if ("scrollRectToVisible".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, com.codename1.ui.Component.class}, false); + typedTarget.scrollRectToVisible(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2]), toIntValue(adaptedArgs[3]), (com.codename1.ui.Component) adaptedArgs[4]); return null; + } + } + if ("setAccessibilityText".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setAccessibilityText((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setAlwaysTensile".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setAlwaysTensile(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setBlockLead".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setBlockLead(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setBoundPropertyValue".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Object.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Object.class}, false); + typedTarget.setBoundPropertyValue((java.lang.String) adaptedArgs[0], (java.lang.Object) adaptedArgs[1]); return null; + } + } + if ("setCellRenderer".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setCellRenderer(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setCloudBoundProperty".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setCloudBoundProperty((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setCloudDestinationProperty".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setCloudDestinationProperty((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setComponentState".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Object.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Object.class}, false); + typedTarget.setComponentState((java.lang.Object) adaptedArgs[0]); return null; + } + } + if ("setCursor".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setCursor(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setDirtyRegion".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.geom.Rectangle.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.geom.Rectangle.class}, false); + typedTarget.setDirtyRegion((com.codename1.ui.geom.Rectangle) adaptedArgs[0]); return null; + } + } + if ("setDisabledStyle".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.plaf.Style.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.plaf.Style.class}, false); + typedTarget.setDisabledStyle((com.codename1.ui.plaf.Style) adaptedArgs[0]); return null; + } + } + if ("setDragTransparency".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Byte.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Byte.class}, false); + typedTarget.setDragTransparency((byte) toIntValue(adaptedArgs[0])); return null; + } + } + if ("setDraggable".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setDraggable(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setDropTarget".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setDropTarget(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setEditingDelegate".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Editable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Editable.class}, false); + typedTarget.setEditingDelegate((com.codename1.ui.Editable) adaptedArgs[0]); return null; + } + } + if ("setEnabled".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setEnabled(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setFacing".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.camera.CameraFacing.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.camera.CameraFacing.class}, false); + typedTarget.setFacing((com.codename1.camera.CameraFacing) adaptedArgs[0]); return null; + } + } + if ("setFlatten".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setFlatten(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setFocus".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setFocus(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setFocusable".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setFocusable(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setGrabsPointerEvents".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setGrabsPointerEvents(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setHandlesInput".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setHandlesInput(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setHeight".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setHeight(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setHidden".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setHidden(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + if (matches(safeArgs, new Class[]{java.lang.Boolean.class, java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class, java.lang.Boolean.class}, false); + typedTarget.setHidden(((Boolean) adaptedArgs[0]).booleanValue(), ((Boolean) adaptedArgs[1]).booleanValue()); return null; + } + } + if ("setHideInLandscape".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setHideInLandscape(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setHideInPortrait".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setHideInPortrait(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setHorizontalScrollBounds".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.setHorizontalScrollBounds(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2]), toIntValue(adaptedArgs[3]), toIntValue(adaptedArgs[4]), toIntValue(adaptedArgs[5]), toIntValue(adaptedArgs[6]), toIntValue(adaptedArgs[7])); return null; + } + } + if ("setIgnorePointerEvents".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setIgnorePointerEvents(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setInlineAllStyles".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setInlineAllStyles((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setInlineDisabledStyles".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setInlineDisabledStyles((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setInlinePressedStyles".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setInlinePressedStyles((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setInlineSelectedStyles".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setInlineSelectedStyles((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setInlineStylesTheme".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.util.Resources.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.util.Resources.class}, false); + typedTarget.setInlineStylesTheme((com.codename1.ui.util.Resources) adaptedArgs[0]); return null; + } + } + if ("setInlineUnselectedStyles".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setInlineUnselectedStyles((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setIsScrollVisible".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setIsScrollVisible(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setLabelForComponent".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Label.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Label.class}, false); + typedTarget.setLabelForComponent((com.codename1.ui.Label) adaptedArgs[0]); return null; + } + } + if ("setLayout".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.layouts.Layout.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.layouts.Layout.class}, false); + typedTarget.setLayout((com.codename1.ui.layouts.Layout) adaptedArgs[0]); return null; + } + } + if ("setLeadComponent".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + typedTarget.setLeadComponent((com.codename1.ui.Component) adaptedArgs[0]); return null; + } + } + if ("setListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ai.vision.VisionPipelineListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ai.vision.VisionPipelineListener.class}, false); + typedTarget.setListener((com.codename1.ai.vision.VisionPipelineListener) adaptedArgs[0]); return null; + } + } + if ("setMaxFps".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setMaxFps(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setName".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setName((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setNextFocusDown".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + typedTarget.setNextFocusDown((com.codename1.ui.Component) adaptedArgs[0]); return null; + } + } + if ("setNextFocusLeft".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + typedTarget.setNextFocusLeft((com.codename1.ui.Component) adaptedArgs[0]); return null; + } + } + if ("setNextFocusRight".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + typedTarget.setNextFocusRight((com.codename1.ui.Component) adaptedArgs[0]); return null; + } + } + if ("setNextFocusUp".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + typedTarget.setNextFocusUp((com.codename1.ui.Component) adaptedArgs[0]); return null; + } + } + if ("setOpaque".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setOpaque(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setOwner".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + typedTarget.setOwner((com.codename1.ui.Component) adaptedArgs[0]); return null; + } + } + if ("setPinchBlocksDragAndDrop".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setPinchBlocksDragAndDrop(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setPreferredH".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setPreferredH(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setPreferredSize".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.geom.Dimension.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.geom.Dimension.class}, false); + typedTarget.setPreferredSize((com.codename1.ui.geom.Dimension) adaptedArgs[0]); return null; + } + } + if ("setPreferredSizeStr".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setPreferredSizeStr((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setPreferredTabIndex".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setPreferredTabIndex(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setPreferredW".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setPreferredW(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setPressedStyle".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.plaf.Style.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.plaf.Style.class}, false); + typedTarget.setPressedStyle((com.codename1.ui.plaf.Style) adaptedArgs[0]); return null; + } + } + if ("setPropertyValue".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Object.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Object.class}, false); + return typedTarget.setPropertyValue((java.lang.String) adaptedArgs[0], (java.lang.Object) adaptedArgs[1]); + } + } + if ("setPullToRefresh".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Runnable.class}, false); + typedTarget.setPullToRefresh((java.lang.Runnable) adaptedArgs[0]); return null; + } + } + if ("setRTL".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setRTL(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setRippleEffect".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setRippleEffect(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setSafeArea".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setSafeArea(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setSafeAreaRoot".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setSafeAreaRoot(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setScaleType".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.camera.ScaleType.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.camera.ScaleType.class}, false); + typedTarget.setScaleType((com.codename1.camera.ScaleType) adaptedArgs[0]); return null; + } + } + if ("setScrollAnimationSpeed".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setScrollAnimationSpeed(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setScrollIncrement".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setScrollIncrement(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setScrollOpacityChangeSpeed".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setScrollOpacityChangeSpeed(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setScrollSize".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.geom.Dimension.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.geom.Dimension.class}, false); + typedTarget.setScrollSize((com.codename1.ui.geom.Dimension) adaptedArgs[0]); return null; + } + } + if ("setScrollVisible".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setScrollVisible(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setScrollable".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setScrollable(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setScrollableX".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setScrollableX(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setScrollableY".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setScrollableY(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setSelectCommandText".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setSelectCommandText((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setSelectedStyle".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.plaf.Style.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.plaf.Style.class}, false); + typedTarget.setSelectedStyle((com.codename1.ui.plaf.Style) adaptedArgs[0]); return null; + } + } + if ("setShouldCalcPreferredSize".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setShouldCalcPreferredSize(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setSize".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.geom.Dimension.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.geom.Dimension.class}, false); + typedTarget.setSize((com.codename1.ui.geom.Dimension) adaptedArgs[0]); return null; + } + } + if ("setSmoothScrolling".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setSmoothScrolling(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setSnapToGrid".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setSnapToGrid(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setTabIndex".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setTabIndex(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setTactileTouch".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setTactileTouch(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setTensileDragEnabled".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setTensileDragEnabled(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setTensileLength".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setTensileLength(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setTooltip".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setTooltip((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("setTorchEnabled".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setTorchEnabled(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setTraversable".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setTraversable(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setUIID".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.setUIID((java.lang.String) adaptedArgs[0]); return null; + } + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false); + typedTarget.setUIID((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); return null; + } + } + if ("setUIManager".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.plaf.UIManager.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.plaf.UIManager.class}, false); + typedTarget.setUIManager((com.codename1.ui.plaf.UIManager) adaptedArgs[0]); return null; + } + } + if ("setUnselectedStyle".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.plaf.Style.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.plaf.Style.class}, false); + typedTarget.setUnselectedStyle((com.codename1.ui.plaf.Style) adaptedArgs[0]); return null; + } + } + if ("setVerticalScrollBounds".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false); + typedTarget.setVerticalScrollBounds(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2]), toIntValue(adaptedArgs[3]), toIntValue(adaptedArgs[4]), toIntValue(adaptedArgs[5]), toIntValue(adaptedArgs[6]), toIntValue(adaptedArgs[7])); return null; + } + } + if ("setVisible".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setVisible(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } + if ("setWidth".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setWidth(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setX".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setX(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setY".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setY(toIntValue(adaptedArgs[0])); return null; + } + } + if ("start".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.start(); return null; + } + } + if ("startEditingAsync".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.startEditingAsync(); return null; + } + } + if ("stop".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.stop(); return null; + } + } + if ("stopEditing".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Runnable.class}, false); + typedTarget.stopEditing((java.lang.Runnable) adaptedArgs[0]); return null; + } + } + if ("stripMarginAndPadding".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.stripMarginAndPadding(); + } + } + if ("styleChanged".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, com.codename1.ui.plaf.Style.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, com.codename1.ui.plaf.Style.class}, false); + typedTarget.styleChanged((java.lang.String) adaptedArgs[0], (com.codename1.ui.plaf.Style) adaptedArgs[1]); return null; + } + } + if ("toImage".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toImage(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + if ("unbindProperty".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, com.codename1.cloud.BindTarget.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, com.codename1.cloud.BindTarget.class}, false); + typedTarget.unbindProperty((java.lang.String) adaptedArgs[0], (com.codename1.cloud.BindTarget) adaptedArgs[1]); return null; + } + } + if ("updateTabIndices".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return typedTarget.updateTabIndices(toIntValue(adaptedArgs[0])); + } + } + if ("visibleBoundsContains".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.visibleBoundsContains(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke12(com.codename1.ai.vision.VisionException typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getCode".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getCode(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke13(com.codename1.ai.vision.VisionImage typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getEncodedBytes".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getEncodedBytes(); + } + } + if ("getEncodedBytesUnsafe".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getEncodedBytesUnsafe(); + } + } + if ("getFormat".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getFormat(); + } + } + if ("getHeight".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getHeight(); + } + } + if ("getPixels".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPixels(); + } + } + if ("getPixelsUnsafe".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPixelsUnsafe(); + } + } + if ("getRotationDegrees".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getRotationDegrees(); + } + } + if ("getTimestampNanos".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTimestampNanos(); + } + } + if ("getWidth".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getWidth(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke14(com.codename1.ai.vision.VisionMetadata typedTarget, String name, Object[] safeArgs) throws Exception { + if ("get".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.get((java.lang.String) adaptedArgs[0]); + } + } + if ("getBackendId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBackendId(); + } + } + if ("getValues".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getValues(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke15(com.codename1.ai.vision.VisionOptions typedTarget, String name, Object[] safeArgs) throws Exception { + if ("backend".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ai.vision.VisionBackend.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ai.vision.VisionBackend.class}, false); + return typedTarget.backend((com.codename1.ai.vision.VisionBackend) adaptedArgs[0]); + } + } + if ("getBackend".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBackend(); + } + } + if ("getMaximumResults".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getMaximumResults(); + } + } + if ("getMinimumConfidence".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getMinimumConfidence(); + } + } + if ("getTextScript".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTextScript(); + } + } + if ("maximumResults".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return typedTarget.maximumResults(toIntValue(adaptedArgs[0])); + } + } + if ("minimumConfidence".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Float.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Float.class}, false); + return typedTarget.minimumConfidence(((Number) adaptedArgs[0]).floatValue()); + } + } + if ("textScript".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ai.vision.TextScript.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ai.vision.TextScript.class}, false); + return typedTarget.textScript((com.codename1.ai.vision.TextScript) adaptedArgs[0]); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke16(com.codename1.ai.vision.VisionPipeline typedTarget, String name, Object[] safeArgs) throws Exception { + if ("close".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.close(); return null; + } + } + if ("isBusy".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isBusy(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke17(com.codename1.ai.vision.VisionPoint typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getX".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getX(); + } + } + if ("getY".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getY(); + } + } + if ("toPoint".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + return typedTarget.toPoint((com.codename1.ui.Component) adaptedArgs[0]); + } + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.toPoint(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2]), toIntValue(adaptedArgs[3])); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke18(com.codename1.ai.vision.VisionRect typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getHeight".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getHeight(); + } + } + if ("getWidth".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getWidth(); + } + } + if ("getX".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getX(); + } + } + if ("getY".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getY(); + } + } + if ("isEmpty".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isEmpty(); + } + } + if ("toBounds".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.Component.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.Component.class}, false); + return typedTarget.toBounds((com.codename1.ui.Component) adaptedArgs[0]); + } + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class}, false); + return typedTarget.toBounds(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2]), toIntValue(adaptedArgs[3])); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke19(com.codename1.ai.vision.VisionAnalyzer typedTarget, String name, Object[] safeArgs) throws Exception { + if ("close".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.close(); return null; + } + } + if ("isSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isSupported(); + } + } + if ("process".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ai.vision.VisionImage.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ai.vision.VisionImage.class}, false); return typedTarget.process((com.codename1.ai.vision.VisionImage) adaptedArgs[0]); } @@ -967,7 +3306,7 @@ private static Object invoke16(com.codename1.ai.vision.VisionAnalyzer typedTarge throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke17(com.codename1.ai.vision.VisionBackend typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke20(com.codename1.ai.vision.VisionBackend typedTarget, String name, Object[] safeArgs) throws Exception { if ("getId".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getId(); @@ -976,7 +3315,7 @@ private static Object invoke17(com.codename1.ai.vision.VisionBackend typedTarget throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke18(com.codename1.ai.vision.VisionPipelineListener typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke21(com.codename1.ai.vision.VisionPipelineListener typedTarget, String name, Object[] safeArgs) throws Exception { if ("error".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Throwable.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Throwable.class}, false); @@ -993,19 +3332,128 @@ private static Object invoke18(com.codename1.ai.vision.VisionPipelineListener ty } public static Object getStaticField(Class type, String name) throws Exception { - if (type == com.codename1.ai.vision.TextRecognitionResult.class) return getStaticField0(name); - if (type == com.codename1.ai.vision.VisionException.class) return getStaticField1(name); - if (type == com.codename1.ai.vision.VisionFeature.class) return getStaticField2(name); - if (type == com.codename1.ai.vision.VisionRect.class) return getStaticField3(name); + if (type == com.codename1.ai.vision.BarcodeFormat.class) return getStaticField0(name); + if (type == com.codename1.ai.vision.FaceLandmarks.class) return getStaticField1(name); + if (type == com.codename1.ai.vision.PoseLandmarks.class) return getStaticField2(name); + if (type == com.codename1.ai.vision.TextRecognitionResult.class) return getStaticField3(name); + if (type == com.codename1.ai.vision.VisionCameraView.class) return getStaticField4(name); + if (type == com.codename1.ai.vision.VisionException.class) return getStaticField5(name); + if (type == com.codename1.ai.vision.VisionFeature.class) return getStaticField6(name); + if (type == com.codename1.ai.vision.VisionRect.class) return getStaticField7(name); throw unsupportedStaticField(type, name); } private static Object getStaticField0(String name) throws Exception { + if ("AZTEC".equals(name)) return com.codename1.ai.vision.BarcodeFormat.AZTEC; + if ("CODABAR".equals(name)) return com.codename1.ai.vision.BarcodeFormat.CODABAR; + if ("CODE_128".equals(name)) return com.codename1.ai.vision.BarcodeFormat.CODE_128; + if ("CODE_39".equals(name)) return com.codename1.ai.vision.BarcodeFormat.CODE_39; + if ("CODE_93".equals(name)) return com.codename1.ai.vision.BarcodeFormat.CODE_93; + if ("DATA_MATRIX".equals(name)) return com.codename1.ai.vision.BarcodeFormat.DATA_MATRIX; + if ("EAN_13".equals(name)) return com.codename1.ai.vision.BarcodeFormat.EAN_13; + if ("EAN_8".equals(name)) return com.codename1.ai.vision.BarcodeFormat.EAN_8; + if ("ITF".equals(name)) return com.codename1.ai.vision.BarcodeFormat.ITF; + if ("PDF417".equals(name)) return com.codename1.ai.vision.BarcodeFormat.PDF417; + if ("QR_CODE".equals(name)) return com.codename1.ai.vision.BarcodeFormat.QR_CODE; + if ("UNKNOWN".equals(name)) return com.codename1.ai.vision.BarcodeFormat.UNKNOWN; + if ("UPC_A".equals(name)) return com.codename1.ai.vision.BarcodeFormat.UPC_A; + if ("UPC_E".equals(name)) return com.codename1.ai.vision.BarcodeFormat.UPC_E; + throw unsupportedStaticField(com.codename1.ai.vision.BarcodeFormat.class, name); + } + + private static Object getStaticField1(String name) throws Exception { + if ("LEFT_EYE".equals(name)) return com.codename1.ai.vision.FaceLandmarks.LEFT_EYE; + if ("MOUTH_LEFT".equals(name)) return com.codename1.ai.vision.FaceLandmarks.MOUTH_LEFT; + if ("MOUTH_RIGHT".equals(name)) return com.codename1.ai.vision.FaceLandmarks.MOUTH_RIGHT; + if ("NOSE_BASE".equals(name)) return com.codename1.ai.vision.FaceLandmarks.NOSE_BASE; + if ("RIGHT_EYE".equals(name)) return com.codename1.ai.vision.FaceLandmarks.RIGHT_EYE; + throw unsupportedStaticField(com.codename1.ai.vision.FaceLandmarks.class, name); + } + + private static Object getStaticField2(String name) throws Exception { + if ("LEFT_ANKLE".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_ANKLE; + if ("LEFT_EAR".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_EAR; + if ("LEFT_ELBOW".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_ELBOW; + if ("LEFT_EYE".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_EYE; + if ("LEFT_EYE_INNER".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_EYE_INNER; + if ("LEFT_EYE_OUTER".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_EYE_OUTER; + if ("LEFT_FOOT_INDEX".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_FOOT_INDEX; + if ("LEFT_HEEL".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_HEEL; + if ("LEFT_HIP".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_HIP; + if ("LEFT_INDEX".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_INDEX; + if ("LEFT_KNEE".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_KNEE; + if ("LEFT_MOUTH".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_MOUTH; + if ("LEFT_PINKY".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_PINKY; + if ("LEFT_SHOULDER".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_SHOULDER; + if ("LEFT_THUMB".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_THUMB; + if ("LEFT_WRIST".equals(name)) return com.codename1.ai.vision.PoseLandmarks.LEFT_WRIST; + if ("NECK".equals(name)) return com.codename1.ai.vision.PoseLandmarks.NECK; + if ("NOSE".equals(name)) return com.codename1.ai.vision.PoseLandmarks.NOSE; + if ("RIGHT_ANKLE".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_ANKLE; + if ("RIGHT_EAR".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_EAR; + if ("RIGHT_ELBOW".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_ELBOW; + if ("RIGHT_EYE".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_EYE; + if ("RIGHT_EYE_INNER".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_EYE_INNER; + if ("RIGHT_EYE_OUTER".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_EYE_OUTER; + if ("RIGHT_FOOT_INDEX".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_FOOT_INDEX; + if ("RIGHT_HEEL".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_HEEL; + if ("RIGHT_HIP".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_HIP; + if ("RIGHT_INDEX".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_INDEX; + if ("RIGHT_KNEE".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_KNEE; + if ("RIGHT_MOUTH".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_MOUTH; + if ("RIGHT_PINKY".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_PINKY; + if ("RIGHT_SHOULDER".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_SHOULDER; + if ("RIGHT_THUMB".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_THUMB; + if ("RIGHT_WRIST".equals(name)) return com.codename1.ai.vision.PoseLandmarks.RIGHT_WRIST; + if ("ROOT".equals(name)) return com.codename1.ai.vision.PoseLandmarks.ROOT; + if ("UNKNOWN".equals(name)) return com.codename1.ai.vision.PoseLandmarks.UNKNOWN; + throw unsupportedStaticField(com.codename1.ai.vision.PoseLandmarks.class, name); + } + + private static Object getStaticField3(String name) throws Exception { if ("EMPTY".equals(name)) return com.codename1.ai.vision.TextRecognitionResult.EMPTY; throw unsupportedStaticField(com.codename1.ai.vision.TextRecognitionResult.class, name); } - private static Object getStaticField1(String name) throws Exception { + private static Object getStaticField4(String name) throws Exception { + if ("BASELINE".equals(name)) return com.codename1.ai.vision.VisionCameraView.BASELINE; + if ("BOTTOM".equals(name)) return com.codename1.ai.vision.VisionCameraView.BOTTOM; + if ("BRB_CENTER_OFFSET".equals(name)) return com.codename1.ai.vision.VisionCameraView.BRB_CENTER_OFFSET; + if ("BRB_CONSTANT_ASCENT".equals(name)) return com.codename1.ai.vision.VisionCameraView.BRB_CONSTANT_ASCENT; + if ("BRB_CONSTANT_DESCENT".equals(name)) return com.codename1.ai.vision.VisionCameraView.BRB_CONSTANT_DESCENT; + if ("BRB_OTHER".equals(name)) return com.codename1.ai.vision.VisionCameraView.BRB_OTHER; + if ("CENTER".equals(name)) return com.codename1.ai.vision.VisionCameraView.CENTER; + if ("CROSSHAIR_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.CROSSHAIR_CURSOR; + if ("DEFAULT_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.DEFAULT_CURSOR; + if ("DRAG_REGION_IMMEDIATELY_DRAG_X".equals(name)) return com.codename1.ai.vision.VisionCameraView.DRAG_REGION_IMMEDIATELY_DRAG_X; + if ("DRAG_REGION_IMMEDIATELY_DRAG_XY".equals(name)) return com.codename1.ai.vision.VisionCameraView.DRAG_REGION_IMMEDIATELY_DRAG_XY; + if ("DRAG_REGION_IMMEDIATELY_DRAG_Y".equals(name)) return com.codename1.ai.vision.VisionCameraView.DRAG_REGION_IMMEDIATELY_DRAG_Y; + if ("DRAG_REGION_LIKELY_DRAG_X".equals(name)) return com.codename1.ai.vision.VisionCameraView.DRAG_REGION_LIKELY_DRAG_X; + if ("DRAG_REGION_LIKELY_DRAG_XY".equals(name)) return com.codename1.ai.vision.VisionCameraView.DRAG_REGION_LIKELY_DRAG_XY; + if ("DRAG_REGION_LIKELY_DRAG_Y".equals(name)) return com.codename1.ai.vision.VisionCameraView.DRAG_REGION_LIKELY_DRAG_Y; + if ("DRAG_REGION_NOT_DRAGGABLE".equals(name)) return com.codename1.ai.vision.VisionCameraView.DRAG_REGION_NOT_DRAGGABLE; + if ("DRAG_REGION_POSSIBLE_DRAG_X".equals(name)) return com.codename1.ai.vision.VisionCameraView.DRAG_REGION_POSSIBLE_DRAG_X; + if ("DRAG_REGION_POSSIBLE_DRAG_XY".equals(name)) return com.codename1.ai.vision.VisionCameraView.DRAG_REGION_POSSIBLE_DRAG_XY; + if ("DRAG_REGION_POSSIBLE_DRAG_Y".equals(name)) return com.codename1.ai.vision.VisionCameraView.DRAG_REGION_POSSIBLE_DRAG_Y; + if ("E_RESIZE_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.E_RESIZE_CURSOR; + if ("HAND_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.HAND_CURSOR; + if ("LEFT".equals(name)) return com.codename1.ai.vision.VisionCameraView.LEFT; + if ("MOVE_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.MOVE_CURSOR; + if ("NE_RESIZE_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.NE_RESIZE_CURSOR; + if ("NW_RESIZE_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.NW_RESIZE_CURSOR; + if ("N_RESIZE_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.N_RESIZE_CURSOR; + if ("RIGHT".equals(name)) return com.codename1.ai.vision.VisionCameraView.RIGHT; + if ("SE_RESIZE_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.SE_RESIZE_CURSOR; + if ("SW_RESIZE_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.SW_RESIZE_CURSOR; + if ("S_RESIZE_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.S_RESIZE_CURSOR; + if ("TEXT_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.TEXT_CURSOR; + if ("TOP".equals(name)) return com.codename1.ai.vision.VisionCameraView.TOP; + if ("WAIT_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.WAIT_CURSOR; + if ("W_RESIZE_CURSOR".equals(name)) return com.codename1.ai.vision.VisionCameraView.W_RESIZE_CURSOR; + throw unsupportedStaticField(com.codename1.ai.vision.VisionCameraView.class, name); + } + + private static Object getStaticField5(String name) throws Exception { if ("BACKEND_ERROR".equals(name)) return com.codename1.ai.vision.VisionException.BACKEND_ERROR; if ("CANCELLED".equals(name)) return com.codename1.ai.vision.VisionException.CANCELLED; if ("INVALID_IMAGE".equals(name)) return com.codename1.ai.vision.VisionException.INVALID_IMAGE; @@ -1014,7 +3462,7 @@ private static Object getStaticField1(String name) throws Exception { throw unsupportedStaticField(com.codename1.ai.vision.VisionException.class, name); } - private static Object getStaticField2(String name) throws Exception { + private static Object getStaticField6(String name) throws Exception { if ("BARCODE_SCANNING".equals(name)) return com.codename1.ai.vision.VisionFeature.BARCODE_SCANNING; if ("DOCUMENT_SCANNING".equals(name)) return com.codename1.ai.vision.VisionFeature.DOCUMENT_SCANNING; if ("FACE_DETECTION".equals(name)) return com.codename1.ai.vision.VisionFeature.FACE_DETECTION; @@ -1025,7 +3473,7 @@ private static Object getStaticField2(String name) throws Exception { throw unsupportedStaticField(com.codename1.ai.vision.VisionFeature.class, name); } - private static Object getStaticField3(String name) throws Exception { + private static Object getStaticField7(String name) throws Exception { if ("EMPTY".equals(name)) return com.codename1.ai.vision.VisionRect.EMPTY; throw unsupportedStaticField(com.codename1.ai.vision.VisionRect.class, name); } diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_annotations.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_annotations.java index 810d22da378..c464ef3bf8f 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_annotations.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_annotations.java @@ -52,6 +52,9 @@ public static Class findClassBySimpleName(String simpleName) { private static Class findClassChunk0(String simpleName) { + if ("AppIntent".equals(simpleName)) { + return com.codename1.annotations.AppIntent.class; + } if ("Async".equals(simpleName)) { return com.codename1.annotations.Async.class; } @@ -88,6 +91,24 @@ private static Class findClassChunk0(String simpleName) { if ("Entity".equals(simpleName)) { return com.codename1.annotations.Entity.class; } + if ("EntityId".equals(simpleName)) { + return com.codename1.annotations.EntityId.class; + } + if ("EntityImage".equals(simpleName)) { + return com.codename1.annotations.EntityImage.class; + } + if ("EntityQuery".equals(simpleName)) { + return com.codename1.annotations.EntityQuery.class; + } + if ("Kind".equals(simpleName)) { + return com.codename1.annotations.EntityQuery.Kind.class; + } + if ("EntitySubtitle".equals(simpleName)) { + return com.codename1.annotations.EntitySubtitle.class; + } + if ("EntityTitle".equals(simpleName)) { + return com.codename1.annotations.EntityTitle.class; + } if ("ExistIn".equals(simpleName)) { return com.codename1.annotations.ExistIn.class; } @@ -97,6 +118,12 @@ private static Class findClassChunk0(String simpleName) { if ("Id".equals(simpleName)) { return com.codename1.annotations.Id.class; } + if ("IntentEntity".equals(simpleName)) { + return com.codename1.annotations.IntentEntity.class; + } + if ("IntentParam".equals(simpleName)) { + return com.codename1.annotations.IntentParam.class; + } if ("JsonIgnore".equals(simpleName)) { return com.codename1.annotations.JsonIgnore.class; } @@ -160,142 +187,170 @@ public static Object invokeStatic(Class type, String name, Object[] args) thr public static Object invoke(Object target, String name, Object[] args) throws Exception { Object[] safeArgs = safeArgs(args); CN1AccessException unsupported = null; + if (target instanceof com.codename1.annotations.AppIntent) { + try { + return invoke0((com.codename1.annotations.AppIntent) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } if (target instanceof com.codename1.annotations.Bind) { try { - return invoke0((com.codename1.annotations.Bind) target, name, safeArgs); + return invoke1((com.codename1.annotations.Bind) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Column) { try { - return invoke1((com.codename1.annotations.Column) target, name, safeArgs); + return invoke2((com.codename1.annotations.Column) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Concrete) { try { - return invoke2((com.codename1.annotations.Concrete) target, name, safeArgs); + return invoke3((com.codename1.annotations.Concrete) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Email) { try { - return invoke3((com.codename1.annotations.Email) target, name, safeArgs); + return invoke4((com.codename1.annotations.Email) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Entity) { try { - return invoke4((com.codename1.annotations.Entity) target, name, safeArgs); + return invoke5((com.codename1.annotations.Entity) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.EntityQuery) { + try { + return invoke6((com.codename1.annotations.EntityQuery) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.ExistIn) { try { - return invoke5((com.codename1.annotations.ExistIn) target, name, safeArgs); + return invoke7((com.codename1.annotations.ExistIn) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Id) { try { - return invoke6((com.codename1.annotations.Id) target, name, safeArgs); + return invoke8((com.codename1.annotations.Id) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.IntentEntity) { + try { + return invoke9((com.codename1.annotations.IntentEntity) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.IntentParam) { + try { + return invoke10((com.codename1.annotations.IntentParam) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.JsonProperty) { try { - return invoke7((com.codename1.annotations.JsonProperty) target, name, safeArgs); + return invoke11((com.codename1.annotations.JsonProperty) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Length) { try { - return invoke8((com.codename1.annotations.Length) target, name, safeArgs); + return invoke12((com.codename1.annotations.Length) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Numeric) { try { - return invoke9((com.codename1.annotations.Numeric) target, name, safeArgs); + return invoke13((com.codename1.annotations.Numeric) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Regex) { try { - return invoke10((com.codename1.annotations.Regex) target, name, safeArgs); + return invoke14((com.codename1.annotations.Regex) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Required) { try { - return invoke11((com.codename1.annotations.Required) target, name, safeArgs); + return invoke15((com.codename1.annotations.Required) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Route) { try { - return invoke12((com.codename1.annotations.Route) target, name, safeArgs); + return invoke16((com.codename1.annotations.Route) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Route.Routes) { try { - return invoke13((com.codename1.annotations.Route.Routes) target, name, safeArgs); + return invoke17((com.codename1.annotations.Route.Routes) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.RouteParam) { try { - return invoke14((com.codename1.annotations.RouteParam) target, name, safeArgs); + return invoke18((com.codename1.annotations.RouteParam) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Url) { try { - return invoke15((com.codename1.annotations.Url) target, name, safeArgs); + return invoke19((com.codename1.annotations.Url) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.Validate) { try { - return invoke16((com.codename1.annotations.Validate) target, name, safeArgs); + return invoke20((com.codename1.annotations.Validate) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.XmlAttribute) { try { - return invoke17((com.codename1.annotations.XmlAttribute) target, name, safeArgs); + return invoke21((com.codename1.annotations.XmlAttribute) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.XmlElement) { try { - return invoke18((com.codename1.annotations.XmlElement) target, name, safeArgs); + return invoke22((com.codename1.annotations.XmlElement) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.annotations.XmlRoot) { try { - return invoke19((com.codename1.annotations.XmlRoot) target, name, safeArgs); + return invoke23((com.codename1.annotations.XmlRoot) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } @@ -306,7 +361,61 @@ public static Object invoke(Object target, String name, Object[] args) throws Ex throw unsupportedInstance(target, name, safeArgs); } - private static Object invoke0(com.codename1.annotations.Bind typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke0(com.codename1.annotations.AppIntent typedTarget, String name, Object[] safeArgs) throws Exception { + if ("description".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.description(); + } + } + if ("destructive".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.destructive(); + } + } + if ("discoverable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.discoverable(); + } + } + if ("exposure".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.exposure(); + } + } + if ("headless".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.headless(); + } + } + if ("opensRoute".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.opensRoute(); + } + } + if ("phrases".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.phrases(); + } + } + if ("timeoutSeconds".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.timeoutSeconds(); + } + } + if ("title".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.title(); + } + } + if ("value".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.value(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke1(com.codename1.annotations.Bind typedTarget, String name, Object[] safeArgs) throws Exception { if ("attr".equals(name)) { if (safeArgs.length == 0) { return typedTarget.attr(); @@ -335,7 +444,7 @@ private static Object invoke0(com.codename1.annotations.Bind typedTarget, String throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke1(com.codename1.annotations.Column typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke2(com.codename1.annotations.Column typedTarget, String name, Object[] safeArgs) throws Exception { if ("name".equals(name)) { if (safeArgs.length == 0) { return typedTarget.name(); @@ -354,7 +463,7 @@ private static Object invoke1(com.codename1.annotations.Column typedTarget, Stri throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke2(com.codename1.annotations.Concrete typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke3(com.codename1.annotations.Concrete typedTarget, String name, Object[] safeArgs) throws Exception { if ("linux".equals(name)) { if (safeArgs.length == 0) { return typedTarget.linux(); @@ -373,7 +482,7 @@ private static Object invoke2(com.codename1.annotations.Concrete typedTarget, St throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke3(com.codename1.annotations.Email typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke4(com.codename1.annotations.Email typedTarget, String name, Object[] safeArgs) throws Exception { if ("message".equals(name)) { if (safeArgs.length == 0) { return typedTarget.message(); @@ -382,7 +491,7 @@ private static Object invoke3(com.codename1.annotations.Email typedTarget, Strin throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke4(com.codename1.annotations.Entity typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke5(com.codename1.annotations.Entity typedTarget, String name, Object[] safeArgs) throws Exception { if ("table".equals(name)) { if (safeArgs.length == 0) { return typedTarget.table(); @@ -391,7 +500,16 @@ private static Object invoke4(com.codename1.annotations.Entity typedTarget, Stri throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke5(com.codename1.annotations.ExistIn typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke6(com.codename1.annotations.EntityQuery typedTarget, String name, Object[] safeArgs) throws Exception { + if ("value".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.value(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke7(com.codename1.annotations.ExistIn typedTarget, String name, Object[] safeArgs) throws Exception { if ("caseSensitive".equals(name)) { if (safeArgs.length == 0) { return typedTarget.caseSensitive(); @@ -410,7 +528,7 @@ private static Object invoke5(com.codename1.annotations.ExistIn typedTarget, Str throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke6(com.codename1.annotations.Id typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke8(com.codename1.annotations.Id typedTarget, String name, Object[] safeArgs) throws Exception { if ("autoIncrement".equals(name)) { if (safeArgs.length == 0) { return typedTarget.autoIncrement(); @@ -419,7 +537,17 @@ private static Object invoke6(com.codename1.annotations.Id typedTarget, String n throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke7(com.codename1.annotations.JsonProperty typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke9(com.codename1.annotations.IntentEntity typedTarget, String name, Object[] safeArgs) throws Exception { + if ("indexed".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.indexed(); + } + } + if ("title".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.title(); + } + } if ("value".equals(name)) { if (safeArgs.length == 0) { return typedTarget.value(); @@ -428,7 +556,45 @@ private static Object invoke7(com.codename1.annotations.JsonProperty typedTarget throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke8(com.codename1.annotations.Length typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke10(com.codename1.annotations.IntentParam typedTarget, String name, Object[] safeArgs) throws Exception { + if ("defaultValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.defaultValue(); + } + } + if ("options".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.options(); + } + } + if ("required".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.required(); + } + } + if ("title".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.title(); + } + } + if ("value".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.value(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke11(com.codename1.annotations.JsonProperty typedTarget, String name, Object[] safeArgs) throws Exception { + if ("value".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.value(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke12(com.codename1.annotations.Length typedTarget, String name, Object[] safeArgs) throws Exception { if ("message".equals(name)) { if (safeArgs.length == 0) { return typedTarget.message(); @@ -442,7 +608,7 @@ private static Object invoke8(com.codename1.annotations.Length typedTarget, Stri throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke9(com.codename1.annotations.Numeric typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke13(com.codename1.annotations.Numeric typedTarget, String name, Object[] safeArgs) throws Exception { if ("decimal".equals(name)) { if (safeArgs.length == 0) { return typedTarget.decimal(); @@ -466,7 +632,7 @@ private static Object invoke9(com.codename1.annotations.Numeric typedTarget, Str throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke10(com.codename1.annotations.Regex typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke14(com.codename1.annotations.Regex typedTarget, String name, Object[] safeArgs) throws Exception { if ("message".equals(name)) { if (safeArgs.length == 0) { return typedTarget.message(); @@ -480,7 +646,7 @@ private static Object invoke10(com.codename1.annotations.Regex typedTarget, Stri throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke11(com.codename1.annotations.Required typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke15(com.codename1.annotations.Required typedTarget, String name, Object[] safeArgs) throws Exception { if ("message".equals(name)) { if (safeArgs.length == 0) { return typedTarget.message(); @@ -489,7 +655,7 @@ private static Object invoke11(com.codename1.annotations.Required typedTarget, S throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke12(com.codename1.annotations.Route typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke16(com.codename1.annotations.Route typedTarget, String name, Object[] safeArgs) throws Exception { if ("value".equals(name)) { if (safeArgs.length == 0) { return typedTarget.value(); @@ -498,7 +664,7 @@ private static Object invoke12(com.codename1.annotations.Route typedTarget, Stri throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke13(com.codename1.annotations.Route.Routes typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke17(com.codename1.annotations.Route.Routes typedTarget, String name, Object[] safeArgs) throws Exception { if ("value".equals(name)) { if (safeArgs.length == 0) { return typedTarget.value(); @@ -507,7 +673,7 @@ private static Object invoke13(com.codename1.annotations.Route.Routes typedTarge throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke14(com.codename1.annotations.RouteParam typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke18(com.codename1.annotations.RouteParam typedTarget, String name, Object[] safeArgs) throws Exception { if ("required".equals(name)) { if (safeArgs.length == 0) { return typedTarget.required(); @@ -521,7 +687,7 @@ private static Object invoke14(com.codename1.annotations.RouteParam typedTarget, throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke15(com.codename1.annotations.Url typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke19(com.codename1.annotations.Url typedTarget, String name, Object[] safeArgs) throws Exception { if ("message".equals(name)) { if (safeArgs.length == 0) { return typedTarget.message(); @@ -530,7 +696,7 @@ private static Object invoke15(com.codename1.annotations.Url typedTarget, String throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke16(com.codename1.annotations.Validate typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke20(com.codename1.annotations.Validate typedTarget, String name, Object[] safeArgs) throws Exception { if ("value".equals(name)) { if (safeArgs.length == 0) { return typedTarget.value(); @@ -539,7 +705,7 @@ private static Object invoke16(com.codename1.annotations.Validate typedTarget, S throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke17(com.codename1.annotations.XmlAttribute typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke21(com.codename1.annotations.XmlAttribute typedTarget, String name, Object[] safeArgs) throws Exception { if ("value".equals(name)) { if (safeArgs.length == 0) { return typedTarget.value(); @@ -548,7 +714,7 @@ private static Object invoke17(com.codename1.annotations.XmlAttribute typedTarge throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke18(com.codename1.annotations.XmlElement typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke22(com.codename1.annotations.XmlElement typedTarget, String name, Object[] safeArgs) throws Exception { if ("value".equals(name)) { if (safeArgs.length == 0) { return typedTarget.value(); @@ -557,7 +723,7 @@ private static Object invoke18(com.codename1.annotations.XmlElement typedTarget, throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke19(com.codename1.annotations.XmlRoot typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke23(com.codename1.annotations.XmlRoot typedTarget, String name, Object[] safeArgs) throws Exception { if ("value".equals(name)) { if (safeArgs.length == 0) { return typedTarget.value(); @@ -567,9 +733,17 @@ private static Object invoke19(com.codename1.annotations.XmlRoot typedTarget, St } public static Object getStaticField(Class type, String name) throws Exception { + if (type == com.codename1.annotations.EntityQuery.Kind.class) return getStaticField0(name); throw unsupportedStaticField(type, name); } + private static Object getStaticField0(String name) throws Exception { + if ("BY_ID".equals(name)) return com.codename1.annotations.EntityQuery.Kind.BY_ID; + if ("SEARCH".equals(name)) return com.codename1.annotations.EntityQuery.Kind.SEARCH; + if ("SUGGESTED".equals(name)) return com.codename1.annotations.EntityQuery.Kind.SUGGESTED; + throw unsupportedStaticField(com.codename1.annotations.EntityQuery.Kind.class, name); + } + public static Object getField(Object target, String name) throws Exception { throw unsupportedField(target, name); } diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_annotations_buildhints.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_annotations_buildhints.java new file mode 100644 index 00000000000..3dbf762dd66 --- /dev/null +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_annotations_buildhints.java @@ -0,0 +1,1153 @@ +/* + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ + +package bsh.cn1.gen; + +import bsh.cn1.CN1AccessException; + +public final class GeneratedAccess_com_codename1_annotations_buildhints { + private GeneratedAccess_com_codename1_annotations_buildhints() { + } + + public static Class findClass(String name) { + if (name == null) { + return null; + } + int dot = name.lastIndexOf('.'); + int dollar = name.lastIndexOf('$'); + int sep = dot > dollar ? dot : dollar; + if (sep < 0 || sep == name.length() - 1) { + return null; + } + return findClassBySimpleName(name.substring(sep + 1)); + } + + public static Class findClassBySimpleName(String simpleName) { + Class found0 = findClassChunk0(simpleName); + if (found0 != null) { + return found0; + } + return null; + } + + + private static Class findClassChunk0(String simpleName) { + if ("Android".equals(simpleName)) { + return com.codename1.annotations.buildhints.Android.class; + } + if ("AndroidThemeMode".equals(simpleName)) { + return com.codename1.annotations.buildhints.AndroidThemeMode.class; + } + if ("Build".equals(simpleName)) { + return com.codename1.annotations.buildhints.Build.class; + } + if ("Desktop".equals(simpleName)) { + return com.codename1.annotations.buildhints.Desktop.class; + } + if ("DesktopTitleBar".equals(simpleName)) { + return com.codename1.annotations.buildhints.DesktopTitleBar.class; + } + if ("HardenControlFlow".equals(simpleName)) { + return com.codename1.annotations.buildhints.HardenControlFlow.class; + } + if ("HardenLevel".equals(simpleName)) { + return com.codename1.annotations.buildhints.HardenLevel.class; + } + if ("HardenStrings".equals(simpleName)) { + return com.codename1.annotations.buildhints.HardenStrings.class; + } + if ("Hardening".equals(simpleName)) { + return com.codename1.annotations.buildhints.Hardening.class; + } + if ("InstallLocation".equals(simpleName)) { + return com.codename1.annotations.buildhints.InstallLocation.class; + } + if ("Ios".equals(simpleName)) { + return com.codename1.annotations.buildhints.Ios.class; + } + if ("IosDependencyManager".equals(simpleName)) { + return com.codename1.annotations.buildhints.IosDependencyManager.class; + } + if ("IosPrivacy".equals(simpleName)) { + return com.codename1.annotations.buildhints.IosPrivacy.class; + } + if ("IosProjectType".equals(simpleName)) { + return com.codename1.annotations.buildhints.IosProjectType.class; + } + if ("IosThemeMode".equals(simpleName)) { + return com.codename1.annotations.buildhints.IosThemeMode.class; + } + if ("NativeThemeMode".equals(simpleName)) { + return com.codename1.annotations.buildhints.NativeThemeMode.class; + } + if ("OnDeviceDebug".equals(simpleName)) { + return com.codename1.annotations.buildhints.OnDeviceDebug.class; + } + return null; + } + public static Object construct(Class type, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + throw unsupportedConstruct(type, safeArgs); + } + + public static Object invokeStatic(Class type, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + throw unsupportedStatic(type, name, safeArgs); + } + + public static Object invoke(Object target, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + CN1AccessException unsupported = null; + if (target instanceof com.codename1.annotations.buildhints.AndroidThemeMode) { + try { + return invoke0((com.codename1.annotations.buildhints.AndroidThemeMode) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.DesktopTitleBar) { + try { + return invoke1((com.codename1.annotations.buildhints.DesktopTitleBar) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.HardenControlFlow) { + try { + return invoke2((com.codename1.annotations.buildhints.HardenControlFlow) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.HardenLevel) { + try { + return invoke3((com.codename1.annotations.buildhints.HardenLevel) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.HardenStrings) { + try { + return invoke4((com.codename1.annotations.buildhints.HardenStrings) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.InstallLocation) { + try { + return invoke5((com.codename1.annotations.buildhints.InstallLocation) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.IosDependencyManager) { + try { + return invoke6((com.codename1.annotations.buildhints.IosDependencyManager) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.IosProjectType) { + try { + return invoke7((com.codename1.annotations.buildhints.IosProjectType) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.IosThemeMode) { + try { + return invoke8((com.codename1.annotations.buildhints.IosThemeMode) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.NativeThemeMode) { + try { + return invoke9((com.codename1.annotations.buildhints.NativeThemeMode) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.Android) { + try { + return invoke10((com.codename1.annotations.buildhints.Android) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.Build) { + try { + return invoke11((com.codename1.annotations.buildhints.Build) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.Desktop) { + try { + return invoke12((com.codename1.annotations.buildhints.Desktop) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.Hardening) { + try { + return invoke13((com.codename1.annotations.buildhints.Hardening) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.Ios) { + try { + return invoke14((com.codename1.annotations.buildhints.Ios) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.IosPrivacy) { + try { + return invoke15((com.codename1.annotations.buildhints.IosPrivacy) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.annotations.buildhints.OnDeviceDebug) { + try { + return invoke16((com.codename1.annotations.buildhints.OnDeviceDebug) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (unsupported != null) { + throw unsupported; + } + throw unsupportedInstance(target, name, safeArgs); + } + + private static Object invoke0(com.codename1.annotations.buildhints.AndroidThemeMode typedTarget, String name, Object[] safeArgs) throws Exception { + if ("wireValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.wireValue(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke1(com.codename1.annotations.buildhints.DesktopTitleBar typedTarget, String name, Object[] safeArgs) throws Exception { + if ("wireValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.wireValue(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke2(com.codename1.annotations.buildhints.HardenControlFlow typedTarget, String name, Object[] safeArgs) throws Exception { + if ("wireValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.wireValue(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke3(com.codename1.annotations.buildhints.HardenLevel typedTarget, String name, Object[] safeArgs) throws Exception { + if ("wireValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.wireValue(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke4(com.codename1.annotations.buildhints.HardenStrings typedTarget, String name, Object[] safeArgs) throws Exception { + if ("wireValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.wireValue(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke5(com.codename1.annotations.buildhints.InstallLocation typedTarget, String name, Object[] safeArgs) throws Exception { + if ("wireValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.wireValue(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke6(com.codename1.annotations.buildhints.IosDependencyManager typedTarget, String name, Object[] safeArgs) throws Exception { + if ("wireValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.wireValue(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke7(com.codename1.annotations.buildhints.IosProjectType typedTarget, String name, Object[] safeArgs) throws Exception { + if ("wireValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.wireValue(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke8(com.codename1.annotations.buildhints.IosThemeMode typedTarget, String name, Object[] safeArgs) throws Exception { + if ("wireValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.wireValue(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke9(com.codename1.annotations.buildhints.NativeThemeMode typedTarget, String name, Object[] safeArgs) throws Exception { + if ("wireValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.wireValue(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke10(com.codename1.annotations.buildhints.Android typedTarget, String name, Object[] safeArgs) throws Exception { + if ("activityLaunchMode".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.activityLaunchMode(); + } + } + if ("appBundle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.appBundle(); + } + } + if ("buildToolsVersion".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.buildToolsVersion(); + } + } + if ("captureRecord".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.captureRecord(); + } + } + if ("debug".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.debug(); + } + } + if ("disableR8".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.disableR8(); + } + } + if ("enableProguard".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.enableProguard(); + } + } + if ("gradleDep".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.gradleDep(); + } + } + if ("hideStatusBar".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.hideStatusBar(); + } + } + if ("installLocation".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.installLocation(); + } + } + if ("licenseKey".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.licenseKey(); + } + } + if ("minSdkVersion".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.minSdkVersion(); + } + } + if ("multidex".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.multidex(); + } + } + if ("newFirebaseMessaging".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.newFirebaseMessaging(); + } + } + if ("proguardKeep".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.proguardKeep(); + } + } + if ("release".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.release(); + } + } + if ("repositories".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.repositories(); + } + } + if ("targetSDKVersion".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.targetSDKVersion(); + } + } + if ("themeMode".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.themeMode(); + } + } + if ("topDependency".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.topDependency(); + } + } + if ("useAndroidX".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.useAndroidX(); + } + } + if ("xapplication".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.xapplication(); + } + } + if ("xgradle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.xgradle(); + } + } + if ("xpermissions".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.xpermissions(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke11(com.codename1.annotations.buildhints.Build typedTarget, String name, Object[] safeArgs) throws Exception { + if ("facebookAppId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.facebookAppId(); + } + } + if ("gcmSenderId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.gcmSenderId(); + } + } + if ("nativeTheme".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.nativeTheme(); + } + } + if ("noExtraResources".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.noExtraResources(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke12(com.codename1.annotations.buildhints.Desktop typedTarget, String name, Object[] safeArgs) throws Exception { + if ("adaptToRetina".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.adaptToRetina(); + } + } + if ("fullscreen".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.fullscreen(); + } + } + if ("height".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.height(); + } + } + if ("interactiveScrollbars".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.interactiveScrollbars(); + } + } + if ("resizable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.resizable(); + } + } + if ("titleBar".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.titleBar(); + } + } + if ("width".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.width(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke13(com.codename1.annotations.buildhints.Hardening typedTarget, String name, Object[] safeArgs) throws Exception { + if ("allowUnhardenedLocalBuild".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.allowUnhardenedLocalBuild(); + } + } + if ("controlFlow".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.controlFlow(); + } + } + if ("keep".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.keep(); + } + } + if ("level".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.level(); + } + } + if ("rename".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.rename(); + } + } + if ("strings".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.strings(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke14(com.codename1.annotations.buildhints.Ios typedTarget, String name, Object[] safeArgs) throws Exception { + if ("addLibs".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.addLibs(); + } + } + if ("applicationQueriesSchemes".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.applicationQueriesSchemes(); + } + } + if ("beforeFinishLaunching".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.beforeFinishLaunching(); + } + } + if ("bundleVersion".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.bundleVersion(); + } + } + if ("dependencyManager".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.dependencyManager(); + } + } + if ("deploymentTarget".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.deploymentTarget(); + } + } + if ("glAppDelegateHeader".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.glAppDelegateHeader(); + } + } + if ("includePush".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.includePush(); + } + } + if ("interfaceOrientation".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.interfaceOrientation(); + } + } + if ("minDeploymentTarget".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.minDeploymentTarget(); + } + } + if ("newStorageLocation".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.newStorageLocation(); + } + } + if ("objC".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.objC(); + } + } + if ("plistInject".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.plistInject(); + } + } + if ("pods".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.pods(); + } + } + if ("podsPlatform".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.podsPlatform(); + } + } + if ("podsSources".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.podsSources(); + } + } + if ("prerenderedIcon".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.prerenderedIcon(); + } + } + if ("projectType".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.projectType(); + } + } + if ("spmPackages".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.spmPackages(); + } + } + if ("teamId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.teamId(); + } + } + if ("themeMode".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.themeMode(); + } + } + if ("uiscene".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.uiscene(); + } + } + if ("urlScheme".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.urlScheme(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke15(com.codename1.annotations.buildhints.IosPrivacy typedTarget, String name, Object[] safeArgs) throws Exception { + if ("calendarsFullAccessUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.calendarsFullAccessUsageDescription(); + } + } + if ("calendarsUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.calendarsUsageDescription(); + } + } + if ("calendarsWriteOnlyAccessUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.calendarsWriteOnlyAccessUsageDescription(); + } + } + if ("cameraUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.cameraUsageDescription(); + } + } + if ("healthShareUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.healthShareUsageDescription(); + } + } + if ("healthUpdateUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.healthUpdateUsageDescription(); + } + } + if ("localNetworkUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.localNetworkUsageDescription(); + } + } + if ("locationAlwaysAndWhenInUseUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.locationAlwaysAndWhenInUseUsageDescription(); + } + } + if ("locationAlwaysUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.locationAlwaysUsageDescription(); + } + } + if ("locationWhenInUseUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.locationWhenInUseUsageDescription(); + } + } + if ("microphoneUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.microphoneUsageDescription(); + } + } + if ("remindersFullAccessUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.remindersFullAccessUsageDescription(); + } + } + if ("remindersUsageDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.remindersUsageDescription(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke16(com.codename1.annotations.buildhints.OnDeviceDebug typedTarget, String name, Object[] safeArgs) throws Exception { + if ("android".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.android(); + } + } + if ("ios".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.ios(); + } + } + if ("iosProxyHost".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.iosProxyHost(); + } + } + if ("iosProxyPort".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.iosProxyPort(); + } + } + if ("iosWaitForAttach".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.iosWaitForAttach(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + public static Object getStaticField(Class type, String name) throws Exception { + if (type == com.codename1.annotations.buildhints.AndroidThemeMode.class) return getStaticField0(name); + if (type == com.codename1.annotations.buildhints.DesktopTitleBar.class) return getStaticField1(name); + if (type == com.codename1.annotations.buildhints.HardenControlFlow.class) return getStaticField2(name); + if (type == com.codename1.annotations.buildhints.HardenLevel.class) return getStaticField3(name); + if (type == com.codename1.annotations.buildhints.HardenStrings.class) return getStaticField4(name); + if (type == com.codename1.annotations.buildhints.InstallLocation.class) return getStaticField5(name); + if (type == com.codename1.annotations.buildhints.IosDependencyManager.class) return getStaticField6(name); + if (type == com.codename1.annotations.buildhints.IosProjectType.class) return getStaticField7(name); + if (type == com.codename1.annotations.buildhints.IosThemeMode.class) return getStaticField8(name); + if (type == com.codename1.annotations.buildhints.NativeThemeMode.class) return getStaticField9(name); + throw unsupportedStaticField(type, name); + } + + private static Object getStaticField0(String name) throws Exception { + if ("AUTO".equals(name)) return com.codename1.annotations.buildhints.AndroidThemeMode.AUTO; + if ("HOLOLIGHT".equals(name)) return com.codename1.annotations.buildhints.AndroidThemeMode.HOLOLIGHT; + if ("LEGACY".equals(name)) return com.codename1.annotations.buildhints.AndroidThemeMode.LEGACY; + if ("MODERN".equals(name)) return com.codename1.annotations.buildhints.AndroidThemeMode.MODERN; + throw unsupportedStaticField(com.codename1.annotations.buildhints.AndroidThemeMode.class, name); + } + + private static Object getStaticField1(String name) throws Exception { + if ("CUSTOM".equals(name)) return com.codename1.annotations.buildhints.DesktopTitleBar.CUSTOM; + if ("NATIVE".equals(name)) return com.codename1.annotations.buildhints.DesktopTitleBar.NATIVE; + if ("TOOLBAR".equals(name)) return com.codename1.annotations.buildhints.DesktopTitleBar.TOOLBAR; + throw unsupportedStaticField(com.codename1.annotations.buildhints.DesktopTitleBar.class, name); + } + + private static Object getStaticField2(String name) throws Exception { + if ("OFF".equals(name)) return com.codename1.annotations.buildhints.HardenControlFlow.OFF; + if ("ON".equals(name)) return com.codename1.annotations.buildhints.HardenControlFlow.ON; + throw unsupportedStaticField(com.codename1.annotations.buildhints.HardenControlFlow.class, name); + } + + private static Object getStaticField3(String name) throws Exception { + if ("AGGRESSIVE".equals(name)) return com.codename1.annotations.buildhints.HardenLevel.AGGRESSIVE; + if ("OFF".equals(name)) return com.codename1.annotations.buildhints.HardenLevel.OFF; + if ("PARANOID".equals(name)) return com.codename1.annotations.buildhints.HardenLevel.PARANOID; + if ("STANDARD".equals(name)) return com.codename1.annotations.buildhints.HardenLevel.STANDARD; + throw unsupportedStaticField(com.codename1.annotations.buildhints.HardenLevel.class, name); + } + + private static Object getStaticField4(String name) throws Exception { + if ("ALL".equals(name)) return com.codename1.annotations.buildhints.HardenStrings.ALL; + if ("CONSTANTS".equals(name)) return com.codename1.annotations.buildhints.HardenStrings.CONSTANTS; + if ("OFF".equals(name)) return com.codename1.annotations.buildhints.HardenStrings.OFF; + throw unsupportedStaticField(com.codename1.annotations.buildhints.HardenStrings.class, name); + } + + private static Object getStaticField5(String name) throws Exception { + if ("AUTO".equals(name)) return com.codename1.annotations.buildhints.InstallLocation.AUTO; + if ("INTERNAL_ONLY".equals(name)) return com.codename1.annotations.buildhints.InstallLocation.INTERNAL_ONLY; + if ("PREFER_EXTERNAL".equals(name)) return com.codename1.annotations.buildhints.InstallLocation.PREFER_EXTERNAL; + throw unsupportedStaticField(com.codename1.annotations.buildhints.InstallLocation.class, name); + } + + private static Object getStaticField6(String name) throws Exception { + if ("AUTO".equals(name)) return com.codename1.annotations.buildhints.IosDependencyManager.AUTO; + if ("BOTH".equals(name)) return com.codename1.annotations.buildhints.IosDependencyManager.BOTH; + if ("COCOAPODS".equals(name)) return com.codename1.annotations.buildhints.IosDependencyManager.COCOAPODS; + if ("NONE".equals(name)) return com.codename1.annotations.buildhints.IosDependencyManager.NONE; + if ("SPM".equals(name)) return com.codename1.annotations.buildhints.IosDependencyManager.SPM; + throw unsupportedStaticField(com.codename1.annotations.buildhints.IosDependencyManager.class, name); + } + + private static Object getStaticField7(String name) throws Exception { + if ("IOS".equals(name)) return com.codename1.annotations.buildhints.IosProjectType.IOS; + if ("IPAD".equals(name)) return com.codename1.annotations.buildhints.IosProjectType.IPAD; + if ("IPHONE".equals(name)) return com.codename1.annotations.buildhints.IosProjectType.IPHONE; + throw unsupportedStaticField(com.codename1.annotations.buildhints.IosProjectType.class, name); + } + + private static Object getStaticField8(String name) throws Exception { + if ("AUTO".equals(name)) return com.codename1.annotations.buildhints.IosThemeMode.AUTO; + if ("IOS7".equals(name)) return com.codename1.annotations.buildhints.IosThemeMode.IOS7; + if ("LEGACY".equals(name)) return com.codename1.annotations.buildhints.IosThemeMode.LEGACY; + if ("MODERN".equals(name)) return com.codename1.annotations.buildhints.IosThemeMode.MODERN; + throw unsupportedStaticField(com.codename1.annotations.buildhints.IosThemeMode.class, name); + } + + private static Object getStaticField9(String name) throws Exception { + if ("CUSTOM".equals(name)) return com.codename1.annotations.buildhints.NativeThemeMode.CUSTOM; + if ("LEGACY".equals(name)) return com.codename1.annotations.buildhints.NativeThemeMode.LEGACY; + if ("MODERN".equals(name)) return com.codename1.annotations.buildhints.NativeThemeMode.MODERN; + throw unsupportedStaticField(com.codename1.annotations.buildhints.NativeThemeMode.class, name); + } + + public static Object getField(Object target, String name) throws Exception { + throw unsupportedField(target, name); + } + + public static void setStaticField(Class type, String name, Object value) throws Exception { + throw unsupportedStaticFieldWrite(type, name, value); + } + + public static void setField(Object target, String name, Object value) throws Exception { + throw unsupportedFieldWrite(target, name, value); + } + + private static Object[] safeArgs(Object[] args) { + return args == null ? new Object[0] : args; + } + + private static Object[] adaptArgs(Object[] args, Class[] paramTypes, boolean varArgs) { + if (args == null || args.length == 0) { + return args == null ? new Object[0] : args; + } + Object[] adapted = args.clone(); + if (!varArgs) { + for (int i = 0; i < Math.min(adapted.length, paramTypes.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + return adapted; + } + if (paramTypes.length == 0) { + return adapted; + } + int fixedCount = paramTypes.length - 1; + for (int i = 0; i < Math.min(fixedCount, adapted.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < adapted.length; i++) { + adapted[i] = adaptValue(adapted[i], componentType); + } + return adapted; + } + + private static boolean isSamInterface(Class type) { + if (type == com.codename1.util.OnComplete.class) { + return true; + } + if (type == com.codename1.util.SuccessCallback.class) { + return true; + } + if (type == com.codename1.util.FailureCallback.class) { + return true; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return true; + } + if (type == java.lang.Runnable.class) { + return true; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return true; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return true; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return true; + } + return false; + } + + private static Object adaptLambdaValue(final bsh.cn1.CN1LambdaSupport.LambdaValue lambda, Class type) { + if (type == com.codename1.util.OnComplete.class) { + return new com.codename1.util.OnComplete() { + public void completed(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.SuccessCallback.class) { + return new com.codename1.util.SuccessCallback() { + public void onSucess(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.FailureCallback.class) { + return new com.codename1.util.FailureCallback() { + public void onError(java.lang.Object arg0, java.lang.Throwable arg1, int arg2, java.lang.String arg3) { + try { + lambda.invoke(new Object[]{arg0, arg1, arg2, arg3}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return new com.codename1.ui.events.ActionListener() { + public void actionPerformed(com.codename1.ui.events.ActionEvent arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == java.lang.Runnable.class) { + return new java.lang.Runnable() { + public void run() { + try { + lambda.invoke(new Object[0]); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return new com.codename1.ui.events.DataChangedListener() { + public void dataChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return new com.codename1.ui.events.SelectionListener() { + public void selectionChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return new com.codename1.printing.PrintResultListener() { + public void onResult(com.codename1.printing.PrintResult arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + return lambda; + } + + private static Object adaptValue(Object value, Class type) { + if (!(value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue)) { + return value; + } + // Direct fit when LambdaValue already implements the target SAM + // (Runnable, Function, Comparator, ...). + if (type.isInstance(value)) { + return value; + } + return adaptLambdaValue((bsh.cn1.CN1LambdaSupport.LambdaValue) value, type); + } + + private static int toIntValue(Object value) { + if (value instanceof Number) return ((Number) value).intValue(); + if (value instanceof Character) return (int) ((Character) value).charValue(); + throw new ClassCastException("Cannot coerce " + + (value == null ? "null" : value.getClass().getName()) + " to int"); + } + + private static boolean matches(Object[] args, Class[] paramTypes, boolean varArgs) { + if (!varArgs) { + if (args.length != paramTypes.length) { + return false; + } + for (int i = 0; i < paramTypes.length; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + return true; + } + if (paramTypes.length == 0) { + return true; + } + int fixedCount = paramTypes.length - 1; + if (args.length < fixedCount) { + return false; + } + for (int i = 0; i < fixedCount; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < args.length; i++) { + if (!matchesType(args[i], componentType)) { + return false; + } + } + return true; + } + + private static boolean matchesType(Object value, Class type) { + if (type == Object.class) { + return true; + } + if (value == null) { + return !type.isPrimitive(); + } + if (type.isArray()) { + return type.isInstance(value); + } + if ("boolean".equals(type.getName()) || type == Boolean.class) { + return value instanceof Boolean; + } + if ("char".equals(type.getName()) || type == Character.class) { + return value instanceof Character; + } + if ("byte".equals(type.getName()) || type == Byte.class || "short".equals(type.getName()) || type == Short.class + || "int".equals(type.getName()) || type == Integer.class || "long".equals(type.getName()) || type == Long.class + || "float".equals(type.getName()) || type == Float.class || "double".equals(type.getName()) || type == Double.class) { + // Java widens char to int implicitly, so accept Character + // for any int-or-larger numeric slot. + return value instanceof Number || value instanceof Character; + } + if (value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue) { + // LambdaValue implements common SAMs directly (Runnable, + // Function, Predicate, Comparator, ...). Also accept any + // CN1 SAM the listener-bridge knows how to wrap. + return type.isInstance(value) || isSamInterface(type); + } + return type.isInstance(value); + } + + private static CN1AccessException unsupportedConstruct(Class type, Object[] args) { + return new CN1AccessException("Generated constructor dispatch not implemented for " + type.getName() + describeArgs(args)); + } + + private static CN1AccessException unsupportedStatic(Class type, String name, Object[] args) { + return new CN1AccessException("Generated static dispatch not implemented for " + type.getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedInstance(Object target, String name, Object[] args) { + return new CN1AccessException("Generated instance dispatch not implemented for " + target.getClass().getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedStaticField(Class type, String name) { + return new CN1AccessException("Generated static field access not implemented for " + type.getName() + "." + name); + } + + private static CN1AccessException unsupportedField(Object target, String name) { + return new CN1AccessException("Generated field access not implemented for " + target.getClass().getName() + "." + name); + } + + private static CN1AccessException unsupportedStaticFieldWrite(Class type, String name, Object value) { + return new CN1AccessException("Generated static field write not implemented for " + type.getName() + "." + name + " value=" + describeValue(value)); + } + + private static CN1AccessException unsupportedFieldWrite(Object target, String name, Object value) { + return new CN1AccessException("Generated field write not implemented for " + target.getClass().getName() + "." + name + " value=" + describeValue(value)); + } + + private static String describeArgs(Object[] args) { + if (args == null || args.length == 0) { + return "()"; + } + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < args.length; i++) { + if (i > 0) { + sb.append(", "); + } + sb.append(describeValue(args[i])); + } + sb.append(')'); + return sb.toString(); + } + + private static String describeValue(Object value) { + return value == null ? "null" : value.getClass().getName(); + } +} diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_crash.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_crash.java index a89227ff424..b6a1894fd65 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_crash.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_crash.java @@ -143,6 +143,12 @@ private static Object invoke0(com.codename1.crash.PiiScrubber typedTarget, Strin return typedTarget.scrubMessage((java.lang.String) adaptedArgs[0]); } } + if ("scrubRawStack".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.scrubRawStack((java.lang.String) adaptedArgs[0]); + } + } throw unsupportedInstance(typedTarget, name, safeArgs); } diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_db.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_db.java index e6cb467b589..f0230a10e9f 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_db.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_db.java @@ -165,6 +165,12 @@ private static Object invokeStatic0(String name, Object[] safeArgs) throws Excep return com.codename1.db.Database.isCustomPathSupported(); } } + if ("isDatabaseBeingDeleted".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.db.Database.isDatabaseBeingDeleted((java.lang.String) adaptedArgs[0]); + } + } if ("isEncrypted".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); @@ -181,6 +187,12 @@ private static Object invokeStatic0(String name, Object[] safeArgs) throws Excep return com.codename1.db.Database.isLegacyBehavior(); } } + if ("normalizeDatabaseKey".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.db.Database.normalizeDatabaseKey((java.lang.String) adaptedArgs[0]); + } + } if ("openOrCreate".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home.java new file mode 100644 index 00000000000..2d9ba9422db --- /dev/null +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home.java @@ -0,0 +1,2561 @@ +/* + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ + +package bsh.cn1.gen; + +import bsh.cn1.CN1AccessException; + +public final class GeneratedAccess_com_codename1_home { + private GeneratedAccess_com_codename1_home() { + } + + public static Class findClass(String name) { + if (name == null) { + return null; + } + int dot = name.lastIndexOf('.'); + int dollar = name.lastIndexOf('$'); + int sep = dot > dollar ? dot : dollar; + if (sep < 0 || sep == name.length() - 1) { + return null; + } + return findClassBySimpleName(name.substring(sep + 1)); + } + + public static Class findClassBySimpleName(String simpleName) { + Class found0 = findClassChunk0(simpleName); + if (found0 != null) { + return found0; + } + return null; + } + + + private static Class findClassChunk0(String simpleName) { + if ("Accessory".equals(simpleName)) { + return com.codename1.home.Accessory.class; + } + if ("AccessoryCategory".equals(simpleName)) { + return com.codename1.home.AccessoryCategory.class; + } + if ("AccessoryService".equals(simpleName)) { + return com.codename1.home.AccessoryService.class; + } + if ("AirQualityLevel".equals(simpleName)) { + return com.codename1.home.AirQualityLevel.class; + } + if ("AlarmState".equals(simpleName)) { + return com.codename1.home.AlarmState.class; + } + if ("ChargingState".equals(simpleName)) { + return com.codename1.home.ChargingState.class; + } + if ("DoorState".equals(simpleName)) { + return com.codename1.home.DoorState.class; + } + if ("FanMode".equals(simpleName)) { + return com.codename1.home.FanMode.class; + } + if ("HeatingCoolingMode".equals(simpleName)) { + return com.codename1.home.HeatingCoolingMode.class; + } + if ("HomeAuthorizationStatus".equals(simpleName)) { + return com.codename1.home.HomeAuthorizationStatus.class; + } + if ("HomeAvailability".equals(simpleName)) { + return com.codename1.home.HomeAvailability.class; + } + if ("HomeBackend".equals(simpleName)) { + return com.codename1.home.HomeBackend.class; + } + if ("HomeChangeListener".equals(simpleName)) { + return com.codename1.home.HomeChangeListener.class; + } + if ("HomeConfigurationException".equals(simpleName)) { + return com.codename1.home.HomeConfigurationException.class; + } + if ("HomeError".equals(simpleName)) { + return com.codename1.home.HomeError.class; + } + if ("HomeException".equals(simpleName)) { + return com.codename1.home.HomeException.class; + } + if ("HomeRoom".equals(simpleName)) { + return com.codename1.home.HomeRoom.class; + } + if ("HomeStructure".equals(simpleName)) { + return com.codename1.home.HomeStructure.class; + } + if ("HomeStructureEvent".equals(simpleName)) { + return com.codename1.home.HomeStructureEvent.class; + } + if ("HomeStructureListener".equals(simpleName)) { + return com.codename1.home.HomeStructureListener.class; + } + if ("HomeZone".equals(simpleName)) { + return com.codename1.home.HomeZone.class; + } + if ("LockState".equals(simpleName)) { + return com.codename1.home.LockState.class; + } + if ("PositionState".equals(simpleName)) { + return com.codename1.home.PositionState.class; + } + if ("Scene".equals(simpleName)) { + return com.codename1.home.Scene.class; + } + if ("SceneAction".equals(simpleName)) { + return com.codename1.home.SceneAction.class; + } + if ("SceneType".equals(simpleName)) { + return com.codename1.home.SceneType.class; + } + if ("ServiceType".equals(simpleName)) { + return com.codename1.home.ServiceType.class; + } + if ("SmartHome".equals(simpleName)) { + return com.codename1.home.SmartHome.class; + } + if ("StructureChangeKind".equals(simpleName)) { + return com.codename1.home.StructureChangeKind.class; + } + if ("SubscriptionRequest".equals(simpleName)) { + return com.codename1.home.SubscriptionRequest.class; + } + if ("Trait".equals(simpleName)) { + return com.codename1.home.Trait.class; + } + if ("TraitChangeBatch".equals(simpleName)) { + return com.codename1.home.TraitChangeBatch.class; + } + if ("TraitConstraint".equals(simpleName)) { + return com.codename1.home.TraitConstraint.class; + } + if ("TraitReadRequest".equals(simpleName)) { + return com.codename1.home.TraitReadRequest.class; + } + if ("TraitReading".equals(simpleName)) { + return com.codename1.home.TraitReading.class; + } + if ("TraitSubscription".equals(simpleName)) { + return com.codename1.home.TraitSubscription.class; + } + if ("TraitUnit".equals(simpleName)) { + return com.codename1.home.TraitUnit.class; + } + if ("TraitUnitDimension".equals(simpleName)) { + return com.codename1.home.TraitUnitDimension.class; + } + if ("TraitValue".equals(simpleName)) { + return com.codename1.home.TraitValue.class; + } + if ("TraitValueKind".equals(simpleName)) { + return com.codename1.home.TraitValueKind.class; + } + if ("TraitWrite".equals(simpleName)) { + return com.codename1.home.TraitWrite.class; + } + if ("TraitWriteResult".equals(simpleName)) { + return com.codename1.home.TraitWriteResult.class; + } + return null; + } + public static Object construct(Class type, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + if (type == com.codename1.home.Accessory.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class, com.codename1.home.AccessoryCategory.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Boolean.class, java.lang.String.class, java.util.List.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class, com.codename1.home.AccessoryCategory.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Boolean.class, java.lang.String.class, java.util.List.class}, false); + return new com.codename1.home.Accessory((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2], (com.codename1.home.AccessoryCategory) adaptedArgs[3], (java.lang.String) adaptedArgs[4], (java.lang.String) adaptedArgs[5], (java.lang.String) adaptedArgs[6], ((Boolean) adaptedArgs[7]).booleanValue(), (java.lang.String) adaptedArgs[8], (java.util.List) adaptedArgs[9]); + } + } + if (type == com.codename1.home.AccessoryService.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.ServiceType.class, java.lang.Boolean.class, java.util.List.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.ServiceType.class, java.lang.Boolean.class, java.util.List.class}, false); + return new com.codename1.home.AccessoryService((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (com.codename1.home.ServiceType) adaptedArgs[2], ((Boolean) adaptedArgs[3]).booleanValue(), (java.util.List) adaptedArgs[4]); + } + } + if (type == com.codename1.home.HomeConfigurationException.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return new com.codename1.home.HomeConfigurationException((java.lang.String) adaptedArgs[0]); + } + } + if (type == com.codename1.home.HomeException.class) { + if (matches(safeArgs, new Class[]{com.codename1.home.HomeError.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.HomeError.class, java.lang.String.class}, false); + return new com.codename1.home.HomeException((com.codename1.home.HomeError) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); + } + if (matches(safeArgs, new Class[]{com.codename1.home.HomeError.class, java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.HomeError.class, java.lang.String.class, java.lang.String.class}, false); + return new com.codename1.home.HomeException((com.codename1.home.HomeError) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); + } + if (matches(safeArgs, new Class[]{com.codename1.home.HomeError.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.HomeError.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}, false); + return new com.codename1.home.HomeException((com.codename1.home.HomeError) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2], (java.lang.Throwable) adaptedArgs[3]); + } + } + if (type == com.codename1.home.HomeRoom.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class}, false); + return new com.codename1.home.HomeRoom((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); + } + } + if (type == com.codename1.home.HomeStructure.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.util.List.class, java.util.List.class, java.util.List.class, java.util.List.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.util.List.class, java.util.List.class, java.util.List.class, java.util.List.class}, false); + return new com.codename1.home.HomeStructure((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], ((Boolean) adaptedArgs[2]).booleanValue(), ((Boolean) adaptedArgs[3]).booleanValue(), ((Boolean) adaptedArgs[4]).booleanValue(), (java.util.List) adaptedArgs[5], (java.util.List) adaptedArgs[6], (java.util.List) adaptedArgs[7], (java.util.List) adaptedArgs[8]); + } + } + if (type == com.codename1.home.HomeStructureEvent.class) { + if (matches(safeArgs, new Class[]{com.codename1.home.StructureChangeKind.class, java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.StructureChangeKind.class, java.lang.String.class, java.lang.String.class}, false); + return new com.codename1.home.HomeStructureEvent((com.codename1.home.StructureChangeKind) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); + } + } + if (type == com.codename1.home.HomeZone.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.util.List.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.util.List.class}, false); + return new com.codename1.home.HomeZone((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.util.List) adaptedArgs[2]); + } + } + if (type == com.codename1.home.Scene.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class, com.codename1.home.SceneType.class, java.lang.Boolean.class, java.util.List.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class, com.codename1.home.SceneType.class, java.lang.Boolean.class, java.util.List.class}, false); + return new com.codename1.home.Scene((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2], (com.codename1.home.SceneType) adaptedArgs[3], ((Boolean) adaptedArgs[4]).booleanValue(), (java.util.List) adaptedArgs[5]); + } + } + if (type == com.codename1.home.SceneAction.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class, com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class, com.codename1.home.TraitValue.class}, false); + return new com.codename1.home.SceneAction((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (com.codename1.home.Trait) adaptedArgs[2], (com.codename1.home.TraitValue) adaptedArgs[3]); + } + } + if (type == com.codename1.home.SubscriptionRequest.class) { + if (matches(safeArgs, new Class[0], false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[0], false); + return new com.codename1.home.SubscriptionRequest(); + } + } + if (type == com.codename1.home.TraitChangeBatch.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.util.List.class, java.lang.Boolean.class, java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.util.List.class, java.lang.Boolean.class, java.lang.Boolean.class}, false); + return new com.codename1.home.TraitChangeBatch((java.lang.String) adaptedArgs[0], (java.util.List) adaptedArgs[1], ((Boolean) adaptedArgs[2]).booleanValue(), ((Boolean) adaptedArgs[3]).booleanValue()); + } + } + if (type == com.codename1.home.TraitReadRequest.class) { + if (matches(safeArgs, new Class[0], false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[0], false); + return new com.codename1.home.TraitReadRequest(); + } + } + if (type == com.codename1.home.TraitWrite.class) { + if (matches(safeArgs, new Class[]{com.codename1.home.Accessory.class, com.codename1.home.AccessoryService.class, com.codename1.home.Trait.class, com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Accessory.class, com.codename1.home.AccessoryService.class, com.codename1.home.Trait.class, com.codename1.home.TraitValue.class}, false); + return new com.codename1.home.TraitWrite((com.codename1.home.Accessory) adaptedArgs[0], (com.codename1.home.AccessoryService) adaptedArgs[1], (com.codename1.home.Trait) adaptedArgs[2], (com.codename1.home.TraitValue) adaptedArgs[3]); + } + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class, com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class, com.codename1.home.TraitValue.class}, false); + return new com.codename1.home.TraitWrite((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (com.codename1.home.Trait) adaptedArgs[2], (com.codename1.home.TraitValue) adaptedArgs[3]); + } + } + throw unsupportedConstruct(type, safeArgs); + } + + public static Object invokeStatic(Class type, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + if (type == com.codename1.home.AirQualityLevel.class) return invokeStatic0(name, safeArgs); + if (type == com.codename1.home.AlarmState.class) return invokeStatic1(name, safeArgs); + if (type == com.codename1.home.ChargingState.class) return invokeStatic2(name, safeArgs); + if (type == com.codename1.home.DoorState.class) return invokeStatic3(name, safeArgs); + if (type == com.codename1.home.FanMode.class) return invokeStatic4(name, safeArgs); + if (type == com.codename1.home.HeatingCoolingMode.class) return invokeStatic5(name, safeArgs); + if (type == com.codename1.home.HomeError.class) return invokeStatic6(name, safeArgs); + if (type == com.codename1.home.LockState.class) return invokeStatic7(name, safeArgs); + if (type == com.codename1.home.PositionState.class) return invokeStatic8(name, safeArgs); + if (type == com.codename1.home.SmartHome.class) return invokeStatic9(name, safeArgs); + if (type == com.codename1.home.Trait.class) return invokeStatic10(name, safeArgs); + if (type == com.codename1.home.TraitConstraint.class) return invokeStatic11(name, safeArgs); + if (type == com.codename1.home.TraitReading.class) return invokeStatic12(name, safeArgs); + if (type == com.codename1.home.TraitUnit.class) return invokeStatic13(name, safeArgs); + if (type == com.codename1.home.TraitValue.class) return invokeStatic14(name, safeArgs); + if (type == com.codename1.home.TraitWriteResult.class) return invokeStatic15(name, safeArgs); + throw unsupportedStatic(type, name, safeArgs); + } + + private static Object invokeStatic0(String name, Object[] safeArgs) throws Exception { + if ("of".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false); + return com.codename1.home.AirQualityLevel.of((com.codename1.home.TraitValue) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.home.AirQualityLevel.class, name, safeArgs); + } + + private static Object invokeStatic1(String name, Object[] safeArgs) throws Exception { + if ("of".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false); + return com.codename1.home.AlarmState.of((com.codename1.home.TraitValue) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.home.AlarmState.class, name, safeArgs); + } + + private static Object invokeStatic2(String name, Object[] safeArgs) throws Exception { + if ("of".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false); + return com.codename1.home.ChargingState.of((com.codename1.home.TraitValue) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.home.ChargingState.class, name, safeArgs); + } + + private static Object invokeStatic3(String name, Object[] safeArgs) throws Exception { + if ("of".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false); + return com.codename1.home.DoorState.of((com.codename1.home.TraitValue) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.home.DoorState.class, name, safeArgs); + } + + private static Object invokeStatic4(String name, Object[] safeArgs) throws Exception { + if ("of".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false); + return com.codename1.home.FanMode.of((com.codename1.home.TraitValue) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.home.FanMode.class, name, safeArgs); + } + + private static Object invokeStatic5(String name, Object[] safeArgs) throws Exception { + if ("of".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false); + return com.codename1.home.HeatingCoolingMode.of((com.codename1.home.TraitValue) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.home.HeatingCoolingMode.class, name, safeArgs); + } + + private static Object invokeStatic6(String name, Object[] safeArgs) throws Exception { + if ("forName".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.home.HomeError.forName((java.lang.String) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.home.HomeError.class, name, safeArgs); + } + + private static Object invokeStatic7(String name, Object[] safeArgs) throws Exception { + if ("of".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false); + return com.codename1.home.LockState.of((com.codename1.home.TraitValue) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.home.LockState.class, name, safeArgs); + } + + private static Object invokeStatic8(String name, Object[] safeArgs) throws Exception { + if ("of".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false); + return com.codename1.home.PositionState.of((com.codename1.home.TraitValue) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.home.PositionState.class, name, safeArgs); + } + + private static Object invokeStatic9(String name, Object[] safeArgs) throws Exception { + if ("deliverAuthorization".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.String.class}, false); + com.codename1.home.SmartHome.deliverAuthorization(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1]), (java.lang.String) adaptedArgs[2]); return null; + } + } + if ("deliverChanges".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String[].class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String[].class}, false); + com.codename1.home.SmartHome.deliverChanges((java.lang.String) adaptedArgs[0], (java.lang.String[]) adaptedArgs[1]); return null; + } + } + if ("deliverCommissioningResult".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Integer.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Integer.class, java.lang.String.class}, false); + com.codename1.home.SmartHome.deliverCommissioningResult(toIntValue(adaptedArgs[0]), (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2], (java.lang.String) adaptedArgs[3], toIntValue(adaptedArgs[4]), (java.lang.String) adaptedArgs[5]); return null; + } + } + if ("deliverDrained".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.String.class}, false); + com.codename1.home.SmartHome.deliverDrained(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1]), (java.lang.String) adaptedArgs[2]); return null; + } + } + if ("deliverIdentifyResult".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class}, false); + com.codename1.home.SmartHome.deliverIdentifyResult(toIntValue(adaptedArgs[0]), (java.lang.String) adaptedArgs[1]); return null; + } + } + if ("deliverReadings".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String[].class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String[].class, java.lang.String.class}, false); + com.codename1.home.SmartHome.deliverReadings(toIntValue(adaptedArgs[0]), (java.lang.String[]) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); return null; + } + } + if ("deliverRefreshed".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class}, false); + com.codename1.home.SmartHome.deliverRefreshed(toIntValue(adaptedArgs[0]), (java.lang.String) adaptedArgs[1]); return null; + } + } + if ("deliverResyncRequired".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + com.codename1.home.SmartHome.deliverResyncRequired((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("deliverSceneResult".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}, false); + com.codename1.home.SmartHome.deliverSceneResult(toIntValue(adaptedArgs[0]), (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2], (java.lang.String) adaptedArgs[3]); return null; + } + } + if ("deliverStarted".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class, java.lang.String.class}, false); + com.codename1.home.SmartHome.deliverStarted(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1]), (java.lang.String) adaptedArgs[2]); return null; + } + } + if ("deliverWriteResults".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String[].class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String[].class, java.lang.String.class}, false); + com.codename1.home.SmartHome.deliverWriteResults(toIntValue(adaptedArgs[0]), (java.lang.String[]) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); return null; + } + } + if ("getInstance".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.home.SmartHome.getInstance(); + } + } + if ("notifyStructureChanged".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class}, false); + com.codename1.home.SmartHome.notifyStructureChanged(toIntValue(adaptedArgs[0]), (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); return null; + } + } + throw unsupportedStatic(com.codename1.home.SmartHome.class, name, safeArgs); + } + + private static Object invokeStatic10(String name, Object[] safeArgs) throws Exception { + if ("all".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.home.Trait.all(); + } + } + if ("forId".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.home.Trait.forId((java.lang.String) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.home.Trait.class, name, safeArgs); + } + + private static Object invokeStatic11(String name, Object[] safeArgs) throws Exception { + if ("choices".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Trait.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, int[].class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Trait.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, int[].class}, false); + return com.codename1.home.TraitConstraint.choices((com.codename1.home.Trait) adaptedArgs[0], ((Boolean) adaptedArgs[1]).booleanValue(), ((Boolean) adaptedArgs[2]).booleanValue(), ((Boolean) adaptedArgs[3]).booleanValue(), (int[]) adaptedArgs[4]); + } + } + if ("of".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Trait.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Trait.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class}, false); + return com.codename1.home.TraitConstraint.of((com.codename1.home.Trait) adaptedArgs[0], ((Boolean) adaptedArgs[1]).booleanValue(), ((Boolean) adaptedArgs[2]).booleanValue(), ((Boolean) adaptedArgs[3]).booleanValue()); + } + } + if ("ranged".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Trait.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Double.class, java.lang.Double.class, java.lang.Double.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Trait.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Double.class, java.lang.Double.class, java.lang.Double.class}, false); + return com.codename1.home.TraitConstraint.ranged((com.codename1.home.Trait) adaptedArgs[0], ((Boolean) adaptedArgs[1]).booleanValue(), ((Boolean) adaptedArgs[2]).booleanValue(), ((Boolean) adaptedArgs[3]).booleanValue(), ((Number) adaptedArgs[4]).doubleValue(), ((Number) adaptedArgs[5]).doubleValue(), ((Number) adaptedArgs[6]).doubleValue()); + } + } + throw unsupportedStatic(com.codename1.home.TraitConstraint.class, name, safeArgs); + } + + private static Object invokeStatic12(String name, Object[] safeArgs) throws Exception { + if ("absent".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class}, false); + return com.codename1.home.TraitReading.absent((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (com.codename1.home.Trait) adaptedArgs[2]); + } + } + if ("failed".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class, com.codename1.home.HomeError.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class, com.codename1.home.HomeError.class, java.lang.String.class}, false); + return com.codename1.home.TraitReading.failed((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (com.codename1.home.Trait) adaptedArgs[2], (com.codename1.home.HomeError) adaptedArgs[3], (java.lang.String) adaptedArgs[4]); + } + } + if ("of".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class, com.codename1.home.TraitValue.class, java.lang.Long.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class, com.codename1.home.TraitValue.class, java.lang.Long.class}, false); + return com.codename1.home.TraitReading.of((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (com.codename1.home.Trait) adaptedArgs[2], (com.codename1.home.TraitValue) adaptedArgs[3], ((Number) adaptedArgs[4]).longValue()); + } + } + throw unsupportedStatic(com.codename1.home.TraitReading.class, name, safeArgs); + } + + private static Object invokeStatic13(String name, Object[] safeArgs) throws Exception { + if ("convert".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Double.class, com.codename1.home.TraitUnit.class, com.codename1.home.TraitUnit.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Double.class, com.codename1.home.TraitUnit.class, com.codename1.home.TraitUnit.class}, false); + return com.codename1.home.TraitUnit.convert(((Number) adaptedArgs[0]).doubleValue(), (com.codename1.home.TraitUnit) adaptedArgs[1], (com.codename1.home.TraitUnit) adaptedArgs[2]); + } + } + if ("forWireId".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return com.codename1.home.TraitUnit.forWireId(toIntValue(adaptedArgs[0])); + } + } + if ("kelvinToMired".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Double.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Double.class}, false); + return com.codename1.home.TraitUnit.kelvinToMired(((Number) adaptedArgs[0]).doubleValue()); + } + } + if ("miredToKelvin".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Double.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Double.class}, false); + return com.codename1.home.TraitUnit.miredToKelvin(((Number) adaptedArgs[0]).doubleValue()); + } + } + throw unsupportedStatic(com.codename1.home.TraitUnit.class, name, safeArgs); + } + + private static Object invokeStatic14(String name, Object[] safeArgs) throws Exception { + if ("of".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + return com.codename1.home.TraitValue.of(((Boolean) adaptedArgs[0]).booleanValue()); + } + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return com.codename1.home.TraitValue.of(toIntValue(adaptedArgs[0])); + } + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.home.TraitValue.of((java.lang.String) adaptedArgs[0]); + } + if (matches(safeArgs, new Class[]{java.lang.Double.class, com.codename1.home.TraitUnit.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Double.class, com.codename1.home.TraitUnit.class}, false); + return com.codename1.home.TraitValue.of(((Number) adaptedArgs[0]).doubleValue(), (com.codename1.home.TraitUnit) adaptedArgs[1]); + } + } + if ("ofEnum".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Enum.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Enum.class}, false); + return com.codename1.home.TraitValue.ofEnum((java.lang.Enum) adaptedArgs[0]); + } + } + if ("ofEnumOrdinal".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return com.codename1.home.TraitValue.ofEnumOrdinal(toIntValue(adaptedArgs[0])); + } + } + throw unsupportedStatic(com.codename1.home.TraitValue.class, name, safeArgs); + } + + private static Object invokeStatic15(String name, Object[] safeArgs) throws Exception { + if ("applied".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitWrite.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitWrite.class}, false); + return com.codename1.home.TraitWriteResult.applied((com.codename1.home.TraitWrite) adaptedArgs[0]); + } + } + if ("failed".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitWrite.class, com.codename1.home.HomeError.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitWrite.class, com.codename1.home.HomeError.class, java.lang.String.class}, false); + return com.codename1.home.TraitWriteResult.failed((com.codename1.home.TraitWrite) adaptedArgs[0], (com.codename1.home.HomeError) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); + } + } + throw unsupportedStatic(com.codename1.home.TraitWriteResult.class, name, safeArgs); + } + + public static Object invoke(Object target, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + CN1AccessException unsupported = null; + if (target instanceof com.codename1.home.HomeConfigurationException) { + try { + return invoke0((com.codename1.home.HomeConfigurationException) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.Accessory) { + try { + return invoke1((com.codename1.home.Accessory) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.AccessoryService) { + try { + return invoke2((com.codename1.home.AccessoryService) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.DoorState) { + try { + return invoke3((com.codename1.home.DoorState) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.HeatingCoolingMode) { + try { + return invoke4((com.codename1.home.HeatingCoolingMode) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.HomeException) { + try { + return invoke5((com.codename1.home.HomeException) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.HomeRoom) { + try { + return invoke6((com.codename1.home.HomeRoom) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.HomeStructure) { + try { + return invoke7((com.codename1.home.HomeStructure) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.HomeStructureEvent) { + try { + return invoke8((com.codename1.home.HomeStructureEvent) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.HomeZone) { + try { + return invoke9((com.codename1.home.HomeZone) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.LockState) { + try { + return invoke10((com.codename1.home.LockState) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.Scene) { + try { + return invoke11((com.codename1.home.Scene) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.SceneAction) { + try { + return invoke12((com.codename1.home.SceneAction) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.SmartHome) { + try { + return invoke13((com.codename1.home.SmartHome) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.SubscriptionRequest) { + try { + return invoke14((com.codename1.home.SubscriptionRequest) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.Trait) { + try { + return invoke15((com.codename1.home.Trait) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.TraitChangeBatch) { + try { + return invoke16((com.codename1.home.TraitChangeBatch) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.TraitConstraint) { + try { + return invoke17((com.codename1.home.TraitConstraint) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.TraitReadRequest) { + try { + return invoke18((com.codename1.home.TraitReadRequest) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.TraitReading) { + try { + return invoke19((com.codename1.home.TraitReading) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.TraitSubscription) { + try { + return invoke20((com.codename1.home.TraitSubscription) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.TraitUnit) { + try { + return invoke21((com.codename1.home.TraitUnit) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.TraitValue) { + try { + return invoke22((com.codename1.home.TraitValue) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.TraitWrite) { + try { + return invoke23((com.codename1.home.TraitWrite) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.TraitWriteResult) { + try { + return invoke24((com.codename1.home.TraitWriteResult) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.HomeChangeListener) { + try { + return invoke25((com.codename1.home.HomeChangeListener) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.HomeStructureListener) { + try { + return invoke26((com.codename1.home.HomeStructureListener) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (unsupported != null) { + throw unsupported; + } + throw unsupportedInstance(target, name, safeArgs); + } + + private static Object invoke0(com.codename1.home.HomeConfigurationException typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getAccessoryId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessoryId(); + } + } + if ("getError".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getError(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke1(com.codename1.home.Accessory typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getBridgeAccessoryId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBridgeAccessoryId(); + } + } + if ("getCategory".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getCategory(); + } + } + if ("getFirmwareVersion".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getFirmwareVersion(); + } + } + if ("getId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getId(); + } + } + if ("getManufacturer".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getManufacturer(); + } + } + if ("getModel".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getModel(); + } + } + if ("getName".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getName(); + } + } + if ("getPrimaryService".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPrimaryService(); + } + } + if ("getRoomId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getRoomId(); + } + } + if ("getService".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getService((java.lang.String) adaptedArgs[0]); + } + } + if ("getServices".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getServices(); + } + } + if ("getServicesSupporting".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Trait.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Trait.class}, false); + return typedTarget.getServicesSupporting((com.codename1.home.Trait) adaptedArgs[0]); + } + } + if ("isBridged".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isBridged(); + } + } + if ("isReachable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isReachable(); + } + } + if ("supports".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Trait.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Trait.class}, false); + return typedTarget.supports((com.codename1.home.Trait) adaptedArgs[0]); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke2(com.codename1.home.AccessoryService typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getConstraint".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Trait.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Trait.class}, false); + return typedTarget.getConstraint((com.codename1.home.Trait) adaptedArgs[0]); + } + } + if ("getConstraints".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getConstraints(); + } + } + if ("getId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getId(); + } + } + if ("getName".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getName(); + } + } + if ("getTraits".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTraits(); + } + } + if ("getType".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getType(); + } + } + if ("isPrimary".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isPrimary(); + } + } + if ("supports".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Trait.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Trait.class}, false); + return typedTarget.supports((com.codename1.home.Trait) adaptedArgs[0]); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke3(com.codename1.home.DoorState typedTarget, String name, Object[] safeArgs) throws Exception { + if ("isWritable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isWritable(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke4(com.codename1.home.HeatingCoolingMode typedTarget, String name, Object[] safeArgs) throws Exception { + if ("isWritable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isWritable(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke5(com.codename1.home.HomeException typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getAccessoryId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessoryId(); + } + } + if ("getError".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getError(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke6(com.codename1.home.HomeRoom typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getId(); + } + } + if ("getName".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getName(); + } + } + if ("getStructureId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getStructureId(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke7(com.codename1.home.HomeStructure typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getAccessories".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessories(); + } + } + if ("getAccessoriesInRoom".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getAccessoriesInRoom((java.lang.String) adaptedArgs[0]); + } + } + if ("getAccessoriesSupporting".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Trait.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Trait.class}, false); + return typedTarget.getAccessoriesSupporting((com.codename1.home.Trait) adaptedArgs[0]); + } + } + if ("getAccessory".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getAccessory((java.lang.String) adaptedArgs[0]); + } + } + if ("getId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getId(); + } + } + if ("getName".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getName(); + } + } + if ("getRoom".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getRoom((java.lang.String) adaptedArgs[0]); + } + } + if ("getRooms".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getRooms(); + } + } + if ("getScenes".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getScenes(); + } + } + if ("getZones".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getZones(); + } + } + if ("isOwner".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isOwner(); + } + } + if ("isPrimary".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isPrimary(); + } + } + if ("isSceneAuthoringSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isSceneAuthoringSupported(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke8(com.codename1.home.HomeStructureEvent typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getAccessoryId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessoryId(); + } + } + if ("getKind".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getKind(); + } + } + if ("getStructureId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getStructureId(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke9(com.codename1.home.HomeZone typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getId(); + } + } + if ("getName".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getName(); + } + } + if ("getRoomIds".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getRoomIds(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke10(com.codename1.home.LockState typedTarget, String name, Object[] safeArgs) throws Exception { + if ("isWritable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isWritable(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke11(com.codename1.home.Scene typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getActions".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getActions(); + } + } + if ("getId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getId(); + } + } + if ("getName".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getName(); + } + } + if ("getStructureId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getStructureId(); + } + } + if ("getType".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getType(); + } + } + if ("isExecutable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isExecutable(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke12(com.codename1.home.SceneAction typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getAccessoryId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessoryId(); + } + } + if ("getServiceId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getServiceId(); + } + } + if ("getTrait".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTrait(); + } + } + if ("getValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getValue(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke13(com.codename1.home.SmartHome typedTarget, String name, Object[] safeArgs) throws Exception { + if ("addStructureListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.HomeStructureListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.HomeStructureListener.class}, false); + typedTarget.addStructureListener((com.codename1.home.HomeStructureListener) adaptedArgs[0]); return null; + } + } + if ("areIdsPersistent".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.areIdsPersistent(); + } + } + if ("createScene".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.HomeStructure.class, java.lang.String.class, java.util.List.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.HomeStructure.class, java.lang.String.class, java.util.List.class}, false); + return typedTarget.createScene((com.codename1.home.HomeStructure) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.util.List) adaptedArgs[2]); + } + } + if ("deleteScene".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Scene.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Scene.class}, false); + return typedTarget.deleteScene((com.codename1.home.Scene) adaptedArgs[0]); + } + } + if ("drainChanges".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.drainChanges(); + } + } + if ("executeScene".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Scene.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Scene.class}, false); + return typedTarget.executeScene((com.codename1.home.Scene) adaptedArgs[0]); + } + } + if ("findAccessory".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.findAccessory((java.lang.String) adaptedArgs[0]); + } + } + if ("getAuthorizationStatus".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAuthorizationStatus(); + } + } + if ("getAvailability".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAvailability(); + } + } + if ("getBackend".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBackend(); + } + } + if ("getCommissioner".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getCommissioner(); + } + } + if ("getConfigurationProblems".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getConfigurationProblems(); + } + } + if ("getMaxReadBatchSize".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getMaxReadBatchSize(); + } + } + if ("getMaxWriteBatchSize".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getMaxWriteBatchSize(); + } + } + if ("getPrimaryStructure".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPrimaryStructure(); + } + } + if ("getStructures".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getStructures(); + } + } + if ("identify".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Accessory.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Accessory.class}, false); + return typedTarget.identify((com.codename1.home.Accessory) adaptedArgs[0]); + } + } + if ("isAutomationSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isAutomationSupported(); + } + } + if ("isSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isSupported(); + } + } + if ("openEcosystemApp".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.openEcosystemApp(); + } + } + if ("openHomeSettings".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.openHomeSettings(); + } + } + if ("openProviderSetup".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.openProviderSetup(); + } + } + if ("read".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitReadRequest.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitReadRequest.class}, false); + return typedTarget.read((com.codename1.home.TraitReadRequest) adaptedArgs[0]); + } + if (matches(safeArgs, new Class[]{com.codename1.home.Accessory.class, com.codename1.home.AccessoryService.class, com.codename1.home.Trait.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Accessory.class, com.codename1.home.AccessoryService.class, com.codename1.home.Trait.class}, false); + return typedTarget.read((com.codename1.home.Accessory) adaptedArgs[0], (com.codename1.home.AccessoryService) adaptedArgs[1], (com.codename1.home.Trait) adaptedArgs[2]); + } + } + if ("refresh".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.refresh(); + } + } + if ("removeStructureListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.HomeStructureListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.HomeStructureListener.class}, false); + typedTarget.removeStructureListener((com.codename1.home.HomeStructureListener) adaptedArgs[0]); return null; + } + } + if ("requestAuthorization".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.requestAuthorization(); + } + } + if ("subscribe".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.SubscriptionRequest.class, com.codename1.home.HomeChangeListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.SubscriptionRequest.class, com.codename1.home.HomeChangeListener.class}, false); + return typedTarget.subscribe((com.codename1.home.SubscriptionRequest) adaptedArgs[0], (com.codename1.home.HomeChangeListener) adaptedArgs[1]); + } + } + if ("write".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitWrite.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitWrite.class}, false); + return typedTarget.write((com.codename1.home.TraitWrite) adaptedArgs[0]); + } + if (matches(safeArgs, new Class[]{java.util.List.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.util.List.class}, false); + return typedTarget.write((java.util.List) adaptedArgs[0]); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke14(com.codename1.home.SubscriptionRequest typedTarget, String name, Object[] safeArgs) throws Exception { + if ("add".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Accessory.class, com.codename1.home.AccessoryService.class, com.codename1.home.Trait.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Accessory.class, com.codename1.home.AccessoryService.class, com.codename1.home.Trait.class}, false); + return typedTarget.add((com.codename1.home.Accessory) adaptedArgs[0], (com.codename1.home.AccessoryService) adaptedArgs[1], (com.codename1.home.Trait) adaptedArgs[2]); + } + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class}, false); + return typedTarget.add((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (com.codename1.home.Trait) adaptedArgs[2]); + } + } + if ("getAccessoryIds".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessoryIds(); + } + } + if ("getMinIntervalMillis".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getMinIntervalMillis(); + } + } + if ("getServiceIds".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getServiceIds(); + } + } + if ("getTraits".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTraits(); + } + } + if ("isDeliverInitialValues".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isDeliverInitialValues(); + } + } + if ("isEmpty".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isEmpty(); + } + } + if ("setDeliverInitialValues".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + return typedTarget.setDeliverInitialValues(((Boolean) adaptedArgs[0]).booleanValue()); + } + } + if ("setMinIntervalMillis".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return typedTarget.setMinIntervalMillis(toIntValue(adaptedArgs[0])); + } + } + if ("size".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.size(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke15(com.codename1.home.Trait typedTarget, String name, Object[] safeArgs) throws Exception { + if ("acceptsEnumValue".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false); + return typedTarget.acceptsEnumValue((com.codename1.home.TraitValue) adaptedArgs[0]); + } + } + if ("acceptsEnumWrite".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false); + return typedTarget.acceptsEnumWrite((com.codename1.home.TraitValue) adaptedArgs[0]); + } + } + if ("acceptsUnit".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitUnit.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitUnit.class}, false); + return typedTarget.acceptsUnit((com.codename1.home.TraitUnit) adaptedArgs[0]); + } + } + if ("enumValue".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return typedTarget.enumValue(toIntValue(adaptedArgs[0])); + } + } + if ("getId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getId(); + } + } + if ("getNominalMaximum".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getNominalMaximum(); + } + } + if ("getNominalMinimum".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getNominalMinimum(); + } + } + if ("getUnit".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getUnit(); + } + } + if ("getValueKind".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getValueKind(); + } + } + if ("hasNominalRange".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.hasNominalRange(); + } + } + if ("isReadOnly".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isReadOnly(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke16(com.codename1.home.TraitChangeBatch typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getReadings".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getReadings(); + } + } + if ("getSubscriptionId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSubscriptionId(); + } + } + if ("isEmpty".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isEmpty(); + } + } + if ("isInitialDelivery".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isInitialDelivery(); + } + } + if ("isResyncRequired".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isResyncRequired(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke17(com.codename1.home.TraitConstraint typedTarget, String name, Object[] safeArgs) throws Exception { + if ("accepts".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitValue.class}, false); + return typedTarget.accepts((com.codename1.home.TraitValue) adaptedArgs[0]); + } + } + if ("getMaximum".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getMaximum(); + } + } + if ("getMinimum".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getMinimum(); + } + } + if ("getStep".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getStep(); + } + } + if ("getTrait".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTrait(); + } + } + if ("getValidOrdinals".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getValidOrdinals(); + } + } + if ("hasRange".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.hasRange(); + } + } + if ("isReadable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isReadable(); + } + } + if ("isWritable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isWritable(); + } + } + if ("notifiesOnChange".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.notifiesOnChange(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke18(com.codename1.home.TraitReadRequest typedTarget, String name, Object[] safeArgs) throws Exception { + if ("add".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Accessory.class, com.codename1.home.AccessoryService.class, com.codename1.home.Trait.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Accessory.class, com.codename1.home.AccessoryService.class, com.codename1.home.Trait.class}, false); + return typedTarget.add((com.codename1.home.Accessory) adaptedArgs[0], (com.codename1.home.AccessoryService) adaptedArgs[1], (com.codename1.home.Trait) adaptedArgs[2]); + } + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.home.Trait.class}, false); + return typedTarget.add((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (com.codename1.home.Trait) adaptedArgs[2]); + } + } + if ("addAll".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.Accessory.class, com.codename1.home.AccessoryService.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.Accessory.class, com.codename1.home.AccessoryService.class}, false); + return typedTarget.addAll((com.codename1.home.Accessory) adaptedArgs[0], (com.codename1.home.AccessoryService) adaptedArgs[1]); + } + } + if ("getAccessoryIds".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessoryIds(); + } + } + if ("getServiceIds".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getServiceIds(); + } + } + if ("getTraits".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTraits(); + } + } + if ("isAllowCached".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isAllowCached(); + } + } + if ("isEmpty".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isEmpty(); + } + } + if ("setAllowCached".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + return typedTarget.setAllowCached(((Boolean) adaptedArgs[0]).booleanValue()); + } + } + if ("size".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.size(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke19(com.codename1.home.TraitReading typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getAccessoryId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessoryId(); + } + } + if ("getError".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getError(); + } + } + if ("getErrorMessage".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getErrorMessage(); + } + } + if ("getServiceId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getServiceId(); + } + } + if ("getTimestampMillis".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTimestampMillis(); + } + } + if ("getTrait".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTrait(); + } + } + if ("getValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getValue(); + } + } + if ("hasValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.hasValue(); + } + } + if ("isFailed".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isFailed(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke20(com.codename1.home.TraitSubscription typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getId(); + } + } + if ("isActive".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isActive(); + } + } + if ("isPushDelivery".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isPushDelivery(); + } + } + if ("stop".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.stop(); return null; + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke21(com.codename1.home.TraitUnit typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getDimension".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDimension(); + } + } + if ("getWireId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getWireId(); + } + } + if ("isCompatibleWith".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitUnit.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitUnit.class}, false); + return typedTarget.isCompatibleWith((com.codename1.home.TraitUnit) adaptedArgs[0]); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke22(com.codename1.home.TraitValue typedTarget, String name, Object[] safeArgs) throws Exception { + if ("equals".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Object.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Object.class}, false); + return typedTarget.equals((java.lang.Object) adaptedArgs[0]); + } + } + if ("getBoolean".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBoolean(); + } + } + if ("getColorTemperatureKelvin".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getColorTemperatureKelvin(); + } + } + if ("getDouble".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitUnit.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitUnit.class}, false); + return typedTarget.getDouble((com.codename1.home.TraitUnit) adaptedArgs[0]); + } + } + if ("getEnumName".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getEnumName(); + } + } + if ("getEnumOrdinal".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getEnumOrdinal(); + } + } + if ("getInt".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getInt(); + } + } + if ("getKind".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getKind(); + } + } + if ("getRawDouble".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getRawDouble(); + } + } + if ("getRawPlatformValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getRawPlatformValue(); + } + } + if ("getString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getString(); + } + } + if ("getUnit".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getUnit(); + } + } + if ("hasRawPlatformValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.hasRawPlatformValue(); + } + } + if ("hashCode".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.hashCode(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + if ("withRawPlatformValue".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return typedTarget.withRawPlatformValue(toIntValue(adaptedArgs[0])); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke23(com.codename1.home.TraitWrite typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getAccessoryId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessoryId(); + } + } + if ("getAuthorizationData".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAuthorizationData(); + } + } + if ("getServiceId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getServiceId(); + } + } + if ("getTrait".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTrait(); + } + } + if ("getValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getValue(); + } + } + if ("setAuthorizationData".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.setAuthorizationData((java.lang.String) adaptedArgs[0]); + } + } + if ("toSceneAction".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toSceneAction(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke24(com.codename1.home.TraitWriteResult typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getError".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getError(); + } + } + if ("getErrorMessage".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getErrorMessage(); + } + } + if ("getWrite".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getWrite(); + } + } + if ("isApplied".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isApplied(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke25(com.codename1.home.HomeChangeListener typedTarget, String name, Object[] safeArgs) throws Exception { + if ("traitsChanged".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.TraitChangeBatch.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.TraitChangeBatch.class}, false); + typedTarget.traitsChanged((com.codename1.home.TraitChangeBatch) adaptedArgs[0]); return null; + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke26(com.codename1.home.HomeStructureListener typedTarget, String name, Object[] safeArgs) throws Exception { + if ("structureChanged".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.HomeStructureEvent.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.HomeStructureEvent.class}, false); + typedTarget.structureChanged((com.codename1.home.HomeStructureEvent) adaptedArgs[0]); return null; + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + public static Object getStaticField(Class type, String name) throws Exception { + if (type == com.codename1.home.AccessoryCategory.class) return getStaticField0(name); + if (type == com.codename1.home.AirQualityLevel.class) return getStaticField1(name); + if (type == com.codename1.home.AlarmState.class) return getStaticField2(name); + if (type == com.codename1.home.ChargingState.class) return getStaticField3(name); + if (type == com.codename1.home.DoorState.class) return getStaticField4(name); + if (type == com.codename1.home.FanMode.class) return getStaticField5(name); + if (type == com.codename1.home.HeatingCoolingMode.class) return getStaticField6(name); + if (type == com.codename1.home.HomeAuthorizationStatus.class) return getStaticField7(name); + if (type == com.codename1.home.HomeAvailability.class) return getStaticField8(name); + if (type == com.codename1.home.HomeBackend.class) return getStaticField9(name); + if (type == com.codename1.home.HomeError.class) return getStaticField10(name); + if (type == com.codename1.home.LockState.class) return getStaticField11(name); + if (type == com.codename1.home.PositionState.class) return getStaticField12(name); + if (type == com.codename1.home.SceneType.class) return getStaticField13(name); + if (type == com.codename1.home.ServiceType.class) return getStaticField14(name); + if (type == com.codename1.home.StructureChangeKind.class) return getStaticField15(name); + if (type == com.codename1.home.SubscriptionRequest.class) return getStaticField16(name); + if (type == com.codename1.home.Trait.class) return getStaticField17(name); + if (type == com.codename1.home.TraitUnit.class) return getStaticField18(name); + if (type == com.codename1.home.TraitUnitDimension.class) return getStaticField19(name); + if (type == com.codename1.home.TraitValueKind.class) return getStaticField20(name); + throw unsupportedStaticField(type, name); + } + + private static Object getStaticField0(String name) throws Exception { + if ("AIR_PURIFIER".equals(name)) return com.codename1.home.AccessoryCategory.AIR_PURIFIER; + if ("BRIDGE".equals(name)) return com.codename1.home.AccessoryCategory.BRIDGE; + if ("CAMERA".equals(name)) return com.codename1.home.AccessoryCategory.CAMERA; + if ("DOORBELL".equals(name)) return com.codename1.home.AccessoryCategory.DOORBELL; + if ("FAN".equals(name)) return com.codename1.home.AccessoryCategory.FAN; + if ("GARAGE_DOOR_OPENER".equals(name)) return com.codename1.home.AccessoryCategory.GARAGE_DOOR_OPENER; + if ("LIGHT".equals(name)) return com.codename1.home.AccessoryCategory.LIGHT; + if ("LOCK".equals(name)) return com.codename1.home.AccessoryCategory.LOCK; + if ("OTHER".equals(name)) return com.codename1.home.AccessoryCategory.OTHER; + if ("OUTLET".equals(name)) return com.codename1.home.AccessoryCategory.OUTLET; + if ("SECURITY_SYSTEM".equals(name)) return com.codename1.home.AccessoryCategory.SECURITY_SYSTEM; + if ("SENSOR".equals(name)) return com.codename1.home.AccessoryCategory.SENSOR; + if ("SPEAKER".equals(name)) return com.codename1.home.AccessoryCategory.SPEAKER; + if ("SWITCH".equals(name)) return com.codename1.home.AccessoryCategory.SWITCH; + if ("TELEVISION".equals(name)) return com.codename1.home.AccessoryCategory.TELEVISION; + if ("THERMOSTAT".equals(name)) return com.codename1.home.AccessoryCategory.THERMOSTAT; + if ("WINDOW_COVERING".equals(name)) return com.codename1.home.AccessoryCategory.WINDOW_COVERING; + throw unsupportedStaticField(com.codename1.home.AccessoryCategory.class, name); + } + + private static Object getStaticField1(String name) throws Exception { + if ("EXTREMELY_POOR".equals(name)) return com.codename1.home.AirQualityLevel.EXTREMELY_POOR; + if ("FAIR".equals(name)) return com.codename1.home.AirQualityLevel.FAIR; + if ("GOOD".equals(name)) return com.codename1.home.AirQualityLevel.GOOD; + if ("MODERATE".equals(name)) return com.codename1.home.AirQualityLevel.MODERATE; + if ("POOR".equals(name)) return com.codename1.home.AirQualityLevel.POOR; + if ("UNKNOWN".equals(name)) return com.codename1.home.AirQualityLevel.UNKNOWN; + if ("VERY_POOR".equals(name)) return com.codename1.home.AirQualityLevel.VERY_POOR; + throw unsupportedStaticField(com.codename1.home.AirQualityLevel.class, name); + } + + private static Object getStaticField2(String name) throws Exception { + if ("CRITICAL".equals(name)) return com.codename1.home.AlarmState.CRITICAL; + if ("NORMAL".equals(name)) return com.codename1.home.AlarmState.NORMAL; + if ("UNKNOWN".equals(name)) return com.codename1.home.AlarmState.UNKNOWN; + if ("WARNING".equals(name)) return com.codename1.home.AlarmState.WARNING; + throw unsupportedStaticField(com.codename1.home.AlarmState.class, name); + } + + private static Object getStaticField3(String name) throws Exception { + if ("CHARGING".equals(name)) return com.codename1.home.ChargingState.CHARGING; + if ("FULL".equals(name)) return com.codename1.home.ChargingState.FULL; + if ("NOT_CHARGEABLE".equals(name)) return com.codename1.home.ChargingState.NOT_CHARGEABLE; + if ("NOT_CHARGING".equals(name)) return com.codename1.home.ChargingState.NOT_CHARGING; + if ("UNKNOWN".equals(name)) return com.codename1.home.ChargingState.UNKNOWN; + throw unsupportedStaticField(com.codename1.home.ChargingState.class, name); + } + + private static Object getStaticField4(String name) throws Exception { + if ("CLOSED".equals(name)) return com.codename1.home.DoorState.CLOSED; + if ("CLOSING".equals(name)) return com.codename1.home.DoorState.CLOSING; + if ("OPEN".equals(name)) return com.codename1.home.DoorState.OPEN; + if ("OPENING".equals(name)) return com.codename1.home.DoorState.OPENING; + if ("STOPPED".equals(name)) return com.codename1.home.DoorState.STOPPED; + if ("UNKNOWN".equals(name)) return com.codename1.home.DoorState.UNKNOWN; + throw unsupportedStaticField(com.codename1.home.DoorState.class, name); + } + + private static Object getStaticField5(String name) throws Exception { + if ("AUTO".equals(name)) return com.codename1.home.FanMode.AUTO; + if ("HIGH".equals(name)) return com.codename1.home.FanMode.HIGH; + if ("LOW".equals(name)) return com.codename1.home.FanMode.LOW; + if ("MEDIUM".equals(name)) return com.codename1.home.FanMode.MEDIUM; + if ("OFF".equals(name)) return com.codename1.home.FanMode.OFF; + if ("ON".equals(name)) return com.codename1.home.FanMode.ON; + if ("SMART".equals(name)) return com.codename1.home.FanMode.SMART; + throw unsupportedStaticField(com.codename1.home.FanMode.class, name); + } + + private static Object getStaticField6(String name) throws Exception { + if ("AUTO".equals(name)) return com.codename1.home.HeatingCoolingMode.AUTO; + if ("COOL".equals(name)) return com.codename1.home.HeatingCoolingMode.COOL; + if ("HEAT".equals(name)) return com.codename1.home.HeatingCoolingMode.HEAT; + if ("OFF".equals(name)) return com.codename1.home.HeatingCoolingMode.OFF; + if ("OTHER".equals(name)) return com.codename1.home.HeatingCoolingMode.OTHER; + throw unsupportedStaticField(com.codename1.home.HeatingCoolingMode.class, name); + } + + private static Object getStaticField7(String name) throws Exception { + if ("AUTHORIZED".equals(name)) return com.codename1.home.HomeAuthorizationStatus.AUTHORIZED; + if ("DENIED".equals(name)) return com.codename1.home.HomeAuthorizationStatus.DENIED; + if ("NOT_DETERMINED".equals(name)) return com.codename1.home.HomeAuthorizationStatus.NOT_DETERMINED; + if ("RESTRICTED".equals(name)) return com.codename1.home.HomeAuthorizationStatus.RESTRICTED; + if ("UNKNOWN".equals(name)) return com.codename1.home.HomeAuthorizationStatus.UNKNOWN; + throw unsupportedStaticField(com.codename1.home.HomeAuthorizationStatus.class, name); + } + + private static Object getStaticField8(String name) throws Exception { + if ("AVAILABLE".equals(name)) return com.codename1.home.HomeAvailability.AVAILABLE; + if ("COMMISSIONING_ONLY".equals(name)) return com.codename1.home.HomeAvailability.COMMISSIONING_ONLY; + if ("LOCAL_ONLY".equals(name)) return com.codename1.home.HomeAvailability.LOCAL_ONLY; + if ("NOT_CONFIGURED".equals(name)) return com.codename1.home.HomeAvailability.NOT_CONFIGURED; + if ("NOT_STARTED".equals(name)) return com.codename1.home.HomeAvailability.NOT_STARTED; + if ("NOT_SUPPORTED".equals(name)) return com.codename1.home.HomeAvailability.NOT_SUPPORTED; + if ("PERMISSION_DENIED".equals(name)) return com.codename1.home.HomeAvailability.PERMISSION_DENIED; + if ("PERMISSION_REQUIRED".equals(name)) return com.codename1.home.HomeAvailability.PERMISSION_REQUIRED; + if ("PROVIDER_NOT_INSTALLED".equals(name)) return com.codename1.home.HomeAvailability.PROVIDER_NOT_INSTALLED; + if ("PROVIDER_UPDATE_REQUIRED".equals(name)) return com.codename1.home.HomeAvailability.PROVIDER_UPDATE_REQUIRED; + if ("RESTRICTED".equals(name)) return com.codename1.home.HomeAvailability.RESTRICTED; + if ("SIGN_IN_REQUIRED".equals(name)) return com.codename1.home.HomeAvailability.SIGN_IN_REQUIRED; + throw unsupportedStaticField(com.codename1.home.HomeAvailability.class, name); + } + + private static Object getStaticField9(String name) throws Exception { + if ("GOOGLE_HOME".equals(name)) return com.codename1.home.HomeBackend.GOOGLE_HOME; + if ("HOMEKIT".equals(name)) return com.codename1.home.HomeBackend.HOMEKIT; + if ("LOCAL".equals(name)) return com.codename1.home.HomeBackend.LOCAL; + if ("MATTER_COMMISSIONING_ONLY".equals(name)) return com.codename1.home.HomeBackend.MATTER_COMMISSIONING_ONLY; + if ("NONE".equals(name)) return com.codename1.home.HomeBackend.NONE; + throw unsupportedStaticField(com.codename1.home.HomeBackend.class, name); + } + + private static Object getStaticField10(String name) throws Exception { + if ("ACCESSORY_NOT_FOUND".equals(name)) return com.codename1.home.HomeError.ACCESSORY_NOT_FOUND; + if ("ACCESSORY_UNREACHABLE".equals(name)) return com.codename1.home.HomeError.ACCESSORY_UNREACHABLE; + if ("AUTHORIZATION_REQUIRED".equals(name)) return com.codename1.home.HomeError.AUTHORIZATION_REQUIRED; + if ("BUSY".equals(name)) return com.codename1.home.HomeError.BUSY; + if ("COMMISSIONING_FAILED".equals(name)) return com.codename1.home.HomeError.COMMISSIONING_FAILED; + if ("COMMISSIONING_UNAVAILABLE".equals(name)) return com.codename1.home.HomeError.COMMISSIONING_UNAVAILABLE; + if ("ECOSYSTEM_APP_MISSING".equals(name)) return com.codename1.home.HomeError.ECOSYSTEM_APP_MISSING; + if ("INVALID_ARGUMENT".equals(name)) return com.codename1.home.HomeError.INVALID_ARGUMENT; + if ("INVALID_DATA".equals(name)) return com.codename1.home.HomeError.INVALID_DATA; + if ("NOT_CONFIGURED".equals(name)) return com.codename1.home.HomeError.NOT_CONFIGURED; + if ("NOT_SUPPORTED".equals(name)) return com.codename1.home.HomeError.NOT_SUPPORTED; + if ("PIN_REJECTED".equals(name)) return com.codename1.home.HomeError.PIN_REJECTED; + if ("PIN_REQUIRED".equals(name)) return com.codename1.home.HomeError.PIN_REQUIRED; + if ("PROVIDER_UNAVAILABLE".equals(name)) return com.codename1.home.HomeError.PROVIDER_UNAVAILABLE; + if ("PROVIDER_UPDATE_REQUIRED".equals(name)) return com.codename1.home.HomeError.PROVIDER_UPDATE_REQUIRED; + if ("RATE_LIMITED".equals(name)) return com.codename1.home.HomeError.RATE_LIMITED; + if ("READ_ONLY_TRAIT".equals(name)) return com.codename1.home.HomeError.READ_ONLY_TRAIT; + if ("RESTRICTED".equals(name)) return com.codename1.home.HomeError.RESTRICTED; + if ("SIGN_IN_REQUIRED".equals(name)) return com.codename1.home.HomeError.SIGN_IN_REQUIRED; + if ("TIMEOUT".equals(name)) return com.codename1.home.HomeError.TIMEOUT; + if ("TRAIT_NOT_SUPPORTED".equals(name)) return com.codename1.home.HomeError.TRAIT_NOT_SUPPORTED; + if ("UNAUTHORIZED".equals(name)) return com.codename1.home.HomeError.UNAUTHORIZED; + if ("UNIT_MISMATCH".equals(name)) return com.codename1.home.HomeError.UNIT_MISMATCH; + if ("UNKNOWN".equals(name)) return com.codename1.home.HomeError.UNKNOWN; + if ("USER_CANCELED".equals(name)) return com.codename1.home.HomeError.USER_CANCELED; + if ("VALUE_OUT_OF_RANGE".equals(name)) return com.codename1.home.HomeError.VALUE_OUT_OF_RANGE; + if ("WRITE_ONLY_TRAIT".equals(name)) return com.codename1.home.HomeError.WRITE_ONLY_TRAIT; + throw unsupportedStaticField(com.codename1.home.HomeError.class, name); + } + + private static Object getStaticField11(String name) throws Exception { + if ("JAMMED".equals(name)) return com.codename1.home.LockState.JAMMED; + if ("PARTIALLY_LOCKED".equals(name)) return com.codename1.home.LockState.PARTIALLY_LOCKED; + if ("SECURED".equals(name)) return com.codename1.home.LockState.SECURED; + if ("UNKNOWN".equals(name)) return com.codename1.home.LockState.UNKNOWN; + if ("UNSECURED".equals(name)) return com.codename1.home.LockState.UNSECURED; + throw unsupportedStaticField(com.codename1.home.LockState.class, name); + } + + private static Object getStaticField12(String name) throws Exception { + if ("CLOSING".equals(name)) return com.codename1.home.PositionState.CLOSING; + if ("OPENING".equals(name)) return com.codename1.home.PositionState.OPENING; + if ("STOPPED".equals(name)) return com.codename1.home.PositionState.STOPPED; + if ("UNKNOWN".equals(name)) return com.codename1.home.PositionState.UNKNOWN; + throw unsupportedStaticField(com.codename1.home.PositionState.class, name); + } + + private static Object getStaticField13(String name) throws Exception { + if ("ARRIVAL".equals(name)) return com.codename1.home.SceneType.ARRIVAL; + if ("DEPARTURE".equals(name)) return com.codename1.home.SceneType.DEPARTURE; + if ("SLEEP".equals(name)) return com.codename1.home.SceneType.SLEEP; + if ("TRIGGER_OWNED".equals(name)) return com.codename1.home.SceneType.TRIGGER_OWNED; + if ("USER_DEFINED".equals(name)) return com.codename1.home.SceneType.USER_DEFINED; + if ("WAKE_UP".equals(name)) return com.codename1.home.SceneType.WAKE_UP; + throw unsupportedStaticField(com.codename1.home.SceneType.class, name); + } + + private static Object getStaticField14(String name) throws Exception { + if ("AIR_PURIFIER".equals(name)) return com.codename1.home.ServiceType.AIR_PURIFIER; + if ("AIR_QUALITY_SENSOR".equals(name)) return com.codename1.home.ServiceType.AIR_QUALITY_SENSOR; + if ("BATTERY".equals(name)) return com.codename1.home.ServiceType.BATTERY; + if ("CARBON_MONOXIDE_SENSOR".equals(name)) return com.codename1.home.ServiceType.CARBON_MONOXIDE_SENSOR; + if ("CONTACT_SENSOR".equals(name)) return com.codename1.home.ServiceType.CONTACT_SENSOR; + if ("DOOR".equals(name)) return com.codename1.home.ServiceType.DOOR; + if ("FAN".equals(name)) return com.codename1.home.ServiceType.FAN; + if ("GARAGE_DOOR_OPENER".equals(name)) return com.codename1.home.ServiceType.GARAGE_DOOR_OPENER; + if ("HUMIDITY_SENSOR".equals(name)) return com.codename1.home.ServiceType.HUMIDITY_SENSOR; + if ("LEAK_SENSOR".equals(name)) return com.codename1.home.ServiceType.LEAK_SENSOR; + if ("LIGHTBULB".equals(name)) return com.codename1.home.ServiceType.LIGHTBULB; + if ("LIGHT_SENSOR".equals(name)) return com.codename1.home.ServiceType.LIGHT_SENSOR; + if ("LOCK_MECHANISM".equals(name)) return com.codename1.home.ServiceType.LOCK_MECHANISM; + if ("MOTION_SENSOR".equals(name)) return com.codename1.home.ServiceType.MOTION_SENSOR; + if ("OCCUPANCY_SENSOR".equals(name)) return com.codename1.home.ServiceType.OCCUPANCY_SENSOR; + if ("OTHER".equals(name)) return com.codename1.home.ServiceType.OTHER; + if ("OUTLET".equals(name)) return com.codename1.home.ServiceType.OUTLET; + if ("SMOKE_SENSOR".equals(name)) return com.codename1.home.ServiceType.SMOKE_SENSOR; + if ("SPEAKER".equals(name)) return com.codename1.home.ServiceType.SPEAKER; + if ("SWITCH".equals(name)) return com.codename1.home.ServiceType.SWITCH; + if ("TEMPERATURE_SENSOR".equals(name)) return com.codename1.home.ServiceType.TEMPERATURE_SENSOR; + if ("THERMOSTAT".equals(name)) return com.codename1.home.ServiceType.THERMOSTAT; + if ("WINDOW_COVERING".equals(name)) return com.codename1.home.ServiceType.WINDOW_COVERING; + throw unsupportedStaticField(com.codename1.home.ServiceType.class, name); + } + + private static Object getStaticField15(String name) throws Exception { + if ("ACCESSORY_ADDED".equals(name)) return com.codename1.home.StructureChangeKind.ACCESSORY_ADDED; + if ("ACCESSORY_MOVED".equals(name)) return com.codename1.home.StructureChangeKind.ACCESSORY_MOVED; + if ("ACCESSORY_REMOVED".equals(name)) return com.codename1.home.StructureChangeKind.ACCESSORY_REMOVED; + if ("ACCESSORY_RENAMED".equals(name)) return com.codename1.home.StructureChangeKind.ACCESSORY_RENAMED; + if ("AVAILABILITY_CHANGED".equals(name)) return com.codename1.home.StructureChangeKind.AVAILABILITY_CHANGED; + if ("REACHABILITY_CHANGED".equals(name)) return com.codename1.home.StructureChangeKind.REACHABILITY_CHANGED; + if ("SCENES_CHANGED".equals(name)) return com.codename1.home.StructureChangeKind.SCENES_CHANGED; + if ("STRUCTURES_CHANGED".equals(name)) return com.codename1.home.StructureChangeKind.STRUCTURES_CHANGED; + throw unsupportedStaticField(com.codename1.home.StructureChangeKind.class, name); + } + + private static Object getStaticField16(String name) throws Exception { + if ("DEFAULT_MIN_INTERVAL_MILLIS".equals(name)) return com.codename1.home.SubscriptionRequest.DEFAULT_MIN_INTERVAL_MILLIS; + throw unsupportedStaticField(com.codename1.home.SubscriptionRequest.class, name); + } + + private static Object getStaticField17(String name) throws Exception { + if ("AIR_QUALITY".equals(name)) return com.codename1.home.Trait.AIR_QUALITY; + if ("BATTERY_CHARGING".equals(name)) return com.codename1.home.Trait.BATTERY_CHARGING; + if ("BATTERY_LEVEL".equals(name)) return com.codename1.home.Trait.BATTERY_LEVEL; + if ("BATTERY_LOW".equals(name)) return com.codename1.home.Trait.BATTERY_LOW; + if ("BRIGHTNESS".equals(name)) return com.codename1.home.Trait.BRIGHTNESS; + if ("CO2_LEVEL".equals(name)) return com.codename1.home.Trait.CO2_LEVEL; + if ("COLOR_TEMPERATURE".equals(name)) return com.codename1.home.Trait.COLOR_TEMPERATURE; + if ("CONTACT_DETECTED".equals(name)) return com.codename1.home.Trait.CONTACT_DETECTED; + if ("COVERING_MOTION".equals(name)) return com.codename1.home.Trait.COVERING_MOTION; + if ("COVERING_POSITION".equals(name)) return com.codename1.home.Trait.COVERING_POSITION; + if ("COVERING_TILT".equals(name)) return com.codename1.home.Trait.COVERING_TILT; + if ("CO_DETECTED".equals(name)) return com.codename1.home.Trait.CO_DETECTED; + if ("CO_LEVEL".equals(name)) return com.codename1.home.Trait.CO_LEVEL; + if ("CURRENT_HEATING_COOLING".equals(name)) return com.codename1.home.Trait.CURRENT_HEATING_COOLING; + if ("CURRENT_HUMIDITY".equals(name)) return com.codename1.home.Trait.CURRENT_HUMIDITY; + if ("CURRENT_LIGHT_LEVEL".equals(name)) return com.codename1.home.Trait.CURRENT_LIGHT_LEVEL; + if ("CURRENT_TEMPERATURE".equals(name)) return com.codename1.home.Trait.CURRENT_TEMPERATURE; + if ("DOOR_STATE".equals(name)) return com.codename1.home.Trait.DOOR_STATE; + if ("FAN_MODE".equals(name)) return com.codename1.home.Trait.FAN_MODE; + if ("FAN_SPEED".equals(name)) return com.codename1.home.Trait.FAN_SPEED; + if ("HUE".equals(name)) return com.codename1.home.Trait.HUE; + if ("LEAK_DETECTED".equals(name)) return com.codename1.home.Trait.LEAK_DETECTED; + if ("LOCK_STATE".equals(name)) return com.codename1.home.Trait.LOCK_STATE; + if ("MOTION_DETECTED".equals(name)) return com.codename1.home.Trait.MOTION_DETECTED; + if ("MUTE".equals(name)) return com.codename1.home.Trait.MUTE; + if ("OBSTRUCTION_DETECTED".equals(name)) return com.codename1.home.Trait.OBSTRUCTION_DETECTED; + if ("OCCUPANCY_DETECTED".equals(name)) return com.codename1.home.Trait.OCCUPANCY_DETECTED; + if ("ON_OFF".equals(name)) return com.codename1.home.Trait.ON_OFF; + if ("OUTLET_IN_USE".equals(name)) return com.codename1.home.Trait.OUTLET_IN_USE; + if ("PM10_DENSITY".equals(name)) return com.codename1.home.Trait.PM10_DENSITY; + if ("PM2_5_DENSITY".equals(name)) return com.codename1.home.Trait.PM2_5_DENSITY; + if ("SATURATION".equals(name)) return com.codename1.home.Trait.SATURATION; + if ("SMOKE_DETECTED".equals(name)) return com.codename1.home.Trait.SMOKE_DETECTED; + if ("TARGET_COOLING_TEMPERATURE".equals(name)) return com.codename1.home.Trait.TARGET_COOLING_TEMPERATURE; + if ("TARGET_COVERING_POSITION".equals(name)) return com.codename1.home.Trait.TARGET_COVERING_POSITION; + if ("TARGET_COVERING_TILT".equals(name)) return com.codename1.home.Trait.TARGET_COVERING_TILT; + if ("TARGET_DOOR_STATE".equals(name)) return com.codename1.home.Trait.TARGET_DOOR_STATE; + if ("TARGET_HEATING_COOLING".equals(name)) return com.codename1.home.Trait.TARGET_HEATING_COOLING; + if ("TARGET_HEATING_TEMPERATURE".equals(name)) return com.codename1.home.Trait.TARGET_HEATING_TEMPERATURE; + if ("TARGET_HUMIDITY".equals(name)) return com.codename1.home.Trait.TARGET_HUMIDITY; + if ("TARGET_LOCK_STATE".equals(name)) return com.codename1.home.Trait.TARGET_LOCK_STATE; + if ("TARGET_TEMPERATURE".equals(name)) return com.codename1.home.Trait.TARGET_TEMPERATURE; + if ("VOC_DENSITY".equals(name)) return com.codename1.home.Trait.VOC_DENSITY; + if ("VOLUME".equals(name)) return com.codename1.home.Trait.VOLUME; + throw unsupportedStaticField(com.codename1.home.Trait.class, name); + } + + private static Object getStaticField18(String name) throws Exception { + if ("ARC_DEGREE".equals(name)) return com.codename1.home.TraitUnit.ARC_DEGREE; + if ("CELSIUS".equals(name)) return com.codename1.home.TraitUnit.CELSIUS; + if ("FAHRENHEIT".equals(name)) return com.codename1.home.TraitUnit.FAHRENHEIT; + if ("LUX".equals(name)) return com.codename1.home.TraitUnit.LUX; + if ("MICROGRAM_PER_CUBIC_METER".equals(name)) return com.codename1.home.TraitUnit.MICROGRAM_PER_CUBIC_METER; + if ("MIRED".equals(name)) return com.codename1.home.TraitUnit.MIRED; + if ("NONE".equals(name)) return com.codename1.home.TraitUnit.NONE; + if ("PERCENT".equals(name)) return com.codename1.home.TraitUnit.PERCENT; + if ("PPB".equals(name)) return com.codename1.home.TraitUnit.PPB; + if ("PPM".equals(name)) return com.codename1.home.TraitUnit.PPM; + throw unsupportedStaticField(com.codename1.home.TraitUnit.class, name); + } + + private static Object getStaticField19(String name) throws Exception { + if ("ANGLE".equals(name)) return com.codename1.home.TraitUnitDimension.ANGLE; + if ("COLOR_TEMPERATURE".equals(name)) return com.codename1.home.TraitUnitDimension.COLOR_TEMPERATURE; + if ("CONCENTRATION_MASS".equals(name)) return com.codename1.home.TraitUnitDimension.CONCENTRATION_MASS; + if ("CONCENTRATION_PARTS".equals(name)) return com.codename1.home.TraitUnitDimension.CONCENTRATION_PARTS; + if ("DIMENSIONLESS".equals(name)) return com.codename1.home.TraitUnitDimension.DIMENSIONLESS; + if ("ILLUMINANCE".equals(name)) return com.codename1.home.TraitUnitDimension.ILLUMINANCE; + if ("RATIO".equals(name)) return com.codename1.home.TraitUnitDimension.RATIO; + if ("TEMPERATURE".equals(name)) return com.codename1.home.TraitUnitDimension.TEMPERATURE; + throw unsupportedStaticField(com.codename1.home.TraitUnitDimension.class, name); + } + + private static Object getStaticField20(String name) throws Exception { + if ("BOOLEAN".equals(name)) return com.codename1.home.TraitValueKind.BOOLEAN; + if ("DOUBLE".equals(name)) return com.codename1.home.TraitValueKind.DOUBLE; + if ("ENUM".equals(name)) return com.codename1.home.TraitValueKind.ENUM; + if ("INT".equals(name)) return com.codename1.home.TraitValueKind.INT; + if ("STRING".equals(name)) return com.codename1.home.TraitValueKind.STRING; + throw unsupportedStaticField(com.codename1.home.TraitValueKind.class, name); + } + + public static Object getField(Object target, String name) throws Exception { + throw unsupportedField(target, name); + } + + public static void setStaticField(Class type, String name, Object value) throws Exception { + throw unsupportedStaticFieldWrite(type, name, value); + } + + public static void setField(Object target, String name, Object value) throws Exception { + throw unsupportedFieldWrite(target, name, value); + } + + private static Object[] safeArgs(Object[] args) { + return args == null ? new Object[0] : args; + } + + private static Object[] adaptArgs(Object[] args, Class[] paramTypes, boolean varArgs) { + if (args == null || args.length == 0) { + return args == null ? new Object[0] : args; + } + Object[] adapted = args.clone(); + if (!varArgs) { + for (int i = 0; i < Math.min(adapted.length, paramTypes.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + return adapted; + } + if (paramTypes.length == 0) { + return adapted; + } + int fixedCount = paramTypes.length - 1; + for (int i = 0; i < Math.min(fixedCount, adapted.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < adapted.length; i++) { + adapted[i] = adaptValue(adapted[i], componentType); + } + return adapted; + } + + private static boolean isSamInterface(Class type) { + if (type == com.codename1.util.OnComplete.class) { + return true; + } + if (type == com.codename1.util.SuccessCallback.class) { + return true; + } + if (type == com.codename1.util.FailureCallback.class) { + return true; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return true; + } + if (type == java.lang.Runnable.class) { + return true; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return true; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return true; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return true; + } + return false; + } + + private static Object adaptLambdaValue(final bsh.cn1.CN1LambdaSupport.LambdaValue lambda, Class type) { + if (type == com.codename1.util.OnComplete.class) { + return new com.codename1.util.OnComplete() { + public void completed(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.SuccessCallback.class) { + return new com.codename1.util.SuccessCallback() { + public void onSucess(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.FailureCallback.class) { + return new com.codename1.util.FailureCallback() { + public void onError(java.lang.Object arg0, java.lang.Throwable arg1, int arg2, java.lang.String arg3) { + try { + lambda.invoke(new Object[]{arg0, arg1, arg2, arg3}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return new com.codename1.ui.events.ActionListener() { + public void actionPerformed(com.codename1.ui.events.ActionEvent arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == java.lang.Runnable.class) { + return new java.lang.Runnable() { + public void run() { + try { + lambda.invoke(new Object[0]); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return new com.codename1.ui.events.DataChangedListener() { + public void dataChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return new com.codename1.ui.events.SelectionListener() { + public void selectionChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return new com.codename1.printing.PrintResultListener() { + public void onResult(com.codename1.printing.PrintResult arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + return lambda; + } + + private static Object adaptValue(Object value, Class type) { + if (!(value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue)) { + return value; + } + // Direct fit when LambdaValue already implements the target SAM + // (Runnable, Function, Comparator, ...). + if (type.isInstance(value)) { + return value; + } + return adaptLambdaValue((bsh.cn1.CN1LambdaSupport.LambdaValue) value, type); + } + + private static int toIntValue(Object value) { + if (value instanceof Number) return ((Number) value).intValue(); + if (value instanceof Character) return (int) ((Character) value).charValue(); + throw new ClassCastException("Cannot coerce " + + (value == null ? "null" : value.getClass().getName()) + " to int"); + } + + private static boolean matches(Object[] args, Class[] paramTypes, boolean varArgs) { + if (!varArgs) { + if (args.length != paramTypes.length) { + return false; + } + for (int i = 0; i < paramTypes.length; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + return true; + } + if (paramTypes.length == 0) { + return true; + } + int fixedCount = paramTypes.length - 1; + if (args.length < fixedCount) { + return false; + } + for (int i = 0; i < fixedCount; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < args.length; i++) { + if (!matchesType(args[i], componentType)) { + return false; + } + } + return true; + } + + private static boolean matchesType(Object value, Class type) { + if (type == Object.class) { + return true; + } + if (value == null) { + return !type.isPrimitive(); + } + if (type.isArray()) { + return type.isInstance(value); + } + if ("boolean".equals(type.getName()) || type == Boolean.class) { + return value instanceof Boolean; + } + if ("char".equals(type.getName()) || type == Character.class) { + return value instanceof Character; + } + if ("byte".equals(type.getName()) || type == Byte.class || "short".equals(type.getName()) || type == Short.class + || "int".equals(type.getName()) || type == Integer.class || "long".equals(type.getName()) || type == Long.class + || "float".equals(type.getName()) || type == Float.class || "double".equals(type.getName()) || type == Double.class) { + // Java widens char to int implicitly, so accept Character + // for any int-or-larger numeric slot. + return value instanceof Number || value instanceof Character; + } + if (value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue) { + // LambdaValue implements common SAMs directly (Runnable, + // Function, Predicate, Comparator, ...). Also accept any + // CN1 SAM the listener-bridge knows how to wrap. + return type.isInstance(value) || isSamInterface(type); + } + return type.isInstance(value); + } + + private static CN1AccessException unsupportedConstruct(Class type, Object[] args) { + return new CN1AccessException("Generated constructor dispatch not implemented for " + type.getName() + describeArgs(args)); + } + + private static CN1AccessException unsupportedStatic(Class type, String name, Object[] args) { + return new CN1AccessException("Generated static dispatch not implemented for " + type.getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedInstance(Object target, String name, Object[] args) { + return new CN1AccessException("Generated instance dispatch not implemented for " + target.getClass().getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedStaticField(Class type, String name) { + return new CN1AccessException("Generated static field access not implemented for " + type.getName() + "." + name); + } + + private static CN1AccessException unsupportedField(Object target, String name) { + return new CN1AccessException("Generated field access not implemented for " + target.getClass().getName() + "." + name); + } + + private static CN1AccessException unsupportedStaticFieldWrite(Class type, String name, Object value) { + return new CN1AccessException("Generated static field write not implemented for " + type.getName() + "." + name + " value=" + describeValue(value)); + } + + private static CN1AccessException unsupportedFieldWrite(Object target, String name, Object value) { + return new CN1AccessException("Generated field write not implemented for " + target.getClass().getName() + "." + name + " value=" + describeValue(value)); + } + + private static String describeArgs(Object[] args) { + if (args == null || args.length == 0) { + return "()"; + } + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < args.length; i++) { + if (i > 0) { + sb.append(", "); + } + sb.append(describeValue(args[i])); + } + sb.append(')'); + return sb.toString(); + } + + private static String describeValue(Object value) { + return value == null ? "null" : value.getClass().getName(); + } +} diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home_commissioning.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home_commissioning.java new file mode 100644 index 00000000000..9b699890a5e --- /dev/null +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home_commissioning.java @@ -0,0 +1,665 @@ +/* + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ + +package bsh.cn1.gen; + +import bsh.cn1.CN1AccessException; + +public final class GeneratedAccess_com_codename1_home_commissioning { + private GeneratedAccess_com_codename1_home_commissioning() { + } + + public static Class findClass(String name) { + if (name == null) { + return null; + } + int dot = name.lastIndexOf('.'); + int dollar = name.lastIndexOf('$'); + int sep = dot > dollar ? dot : dollar; + if (sep < 0 || sep == name.length() - 1) { + return null; + } + return findClassBySimpleName(name.substring(sep + 1)); + } + + public static Class findClassBySimpleName(String simpleName) { + Class found0 = findClassChunk0(simpleName); + if (found0 != null) { + return found0; + } + return null; + } + + + private static Class findClassChunk0(String simpleName) { + if ("Commissioner".equals(simpleName)) { + return com.codename1.home.commissioning.Commissioner.class; + } + if ("CommissioningRequest".equals(simpleName)) { + return com.codename1.home.commissioning.CommissioningRequest.class; + } + if ("CommissioningResult".equals(simpleName)) { + return com.codename1.home.commissioning.CommissioningResult.class; + } + if ("CommissioningStyle".equals(simpleName)) { + return com.codename1.home.commissioning.CommissioningStyle.class; + } + if ("SetupPayload".equals(simpleName)) { + return com.codename1.home.commissioning.SetupPayload.class; + } + return null; + } + public static Object construct(Class type, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + if (type == com.codename1.home.commissioning.CommissioningRequest.class) { + if (matches(safeArgs, new Class[0], false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[0], false); + return new com.codename1.home.commissioning.CommissioningRequest(); + } + } + if (type == com.codename1.home.commissioning.CommissioningResult.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Boolean.class}, false); + return new com.codename1.home.commissioning.CommissioningResult((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2], ((Boolean) adaptedArgs[3]).booleanValue()); + } + } + throw unsupportedConstruct(type, safeArgs); + } + + public static Object invokeStatic(Class type, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + if (type == com.codename1.home.commissioning.SetupPayload.class) return invokeStatic0(name, safeArgs); + throw unsupportedStatic(type, name, safeArgs); + } + + private static Object invokeStatic0(String name, Object[] safeArgs) throws Exception { + if ("isValid".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.home.commissioning.SetupPayload.isValid((java.lang.String) adaptedArgs[0]); + } + } + if ("parse".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.home.commissioning.SetupPayload.parse((java.lang.String) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.home.commissioning.SetupPayload.class, name, safeArgs); + } + + public static Object invoke(Object target, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + CN1AccessException unsupported = null; + if (target instanceof com.codename1.home.commissioning.Commissioner) { + try { + return invoke0((com.codename1.home.commissioning.Commissioner) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.commissioning.CommissioningRequest) { + try { + return invoke1((com.codename1.home.commissioning.CommissioningRequest) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.commissioning.CommissioningResult) { + try { + return invoke2((com.codename1.home.commissioning.CommissioningResult) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.home.commissioning.SetupPayload) { + try { + return invoke3((com.codename1.home.commissioning.SetupPayload) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (unsupported != null) { + throw unsupported; + } + throw unsupportedInstance(target, name, safeArgs); + } + + private static Object invoke0(com.codename1.home.commissioning.Commissioner typedTarget, String name, Object[] safeArgs) throws Exception { + if ("commission".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.commissioning.CommissioningRequest.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.commissioning.CommissioningRequest.class}, false); + return typedTarget.commission((com.codename1.home.commissioning.CommissioningRequest) adaptedArgs[0]); + } + } + if ("getStyle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getStyle(); + } + } + if ("isSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isSupported(); + } + } + if ("openEcosystemApp".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.openEcosystemApp(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke1(com.codename1.home.commissioning.CommissioningRequest typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getRawSetupPayload".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getRawSetupPayload(); + } + } + if ("getRoomId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getRoomId(); + } + } + if ("getSetupPayload".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSetupPayload(); + } + } + if ("getStructureId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getStructureId(); + } + } + if ("getSuggestedName".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSuggestedName(); + } + } + if ("getTimeoutMillis".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTimeoutMillis(); + } + } + if ("isCommissionToThisApp".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isCommissionToThisApp(); + } + } + if ("setCommissionToThisApp".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + return typedTarget.setCommissionToThisApp(((Boolean) adaptedArgs[0]).booleanValue()); + } + } + if ("setRawSetupPayload".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.setRawSetupPayload((java.lang.String) adaptedArgs[0]); + } + } + if ("setRoom".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.HomeRoom.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.HomeRoom.class}, false); + return typedTarget.setRoom((com.codename1.home.HomeRoom) adaptedArgs[0]); + } + } + if ("setRoomId".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.setRoomId((java.lang.String) adaptedArgs[0]); + } + } + if ("setSetupPayload".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.commissioning.SetupPayload.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.commissioning.SetupPayload.class}, false); + return typedTarget.setSetupPayload((com.codename1.home.commissioning.SetupPayload) adaptedArgs[0]); + } + } + if ("setStructure".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.home.HomeStructure.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.home.HomeStructure.class}, false); + return typedTarget.setStructure((com.codename1.home.HomeStructure) adaptedArgs[0]); + } + } + if ("setStructureId".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.setStructureId((java.lang.String) adaptedArgs[0]); + } + } + if ("setSuggestedName".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.setSuggestedName((java.lang.String) adaptedArgs[0]); + } + } + if ("setTimeoutMillis".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return typedTarget.setTimeoutMillis(toIntValue(adaptedArgs[0])); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke2(com.codename1.home.commissioning.CommissioningResult typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getAccessoryId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessoryId(); + } + } + if ("getAccessoryName".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAccessoryName(); + } + } + if ("getStructureId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getStructureId(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + if ("wasCommissionedToThisApp".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.wasCommissionedToThisApp(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke3(com.codename1.home.commissioning.SetupPayload typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getCustomFlow".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getCustomFlow(); + } + } + if ("getDiscoveryCapabilities".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDiscoveryCapabilities(); + } + } + if ("getDiscriminator".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDiscriminator(); + } + } + if ("getPasscode".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPasscode(); + } + } + if ("getProductId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getProductId(); + } + } + if ("getRaw".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getRaw(); + } + } + if ("getVendorId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getVendorId(); + } + } + if ("getVersion".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getVersion(); + } + } + if ("isFromQrCode".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isFromQrCode(); + } + } + if ("isShortDiscriminator".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isShortDiscriminator(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + public static Object getStaticField(Class type, String name) throws Exception { + if (type == com.codename1.home.commissioning.CommissioningStyle.class) return getStaticField0(name); + if (type == com.codename1.home.commissioning.SetupPayload.class) return getStaticField1(name); + throw unsupportedStaticField(type, name); + } + + private static Object getStaticField0(String name) throws Exception { + if ("ECOSYSTEM_APP_HANDOFF".equals(name)) return com.codename1.home.commissioning.CommissioningStyle.ECOSYSTEM_APP_HANDOFF; + if ("NONE".equals(name)) return com.codename1.home.commissioning.CommissioningStyle.NONE; + if ("OS_OWNED_UI".equals(name)) return com.codename1.home.commissioning.CommissioningStyle.OS_OWNED_UI; + throw unsupportedStaticField(com.codename1.home.commissioning.CommissioningStyle.class, name); + } + + private static Object getStaticField1(String name) throws Exception { + if ("DISCOVERY_BLE".equals(name)) return com.codename1.home.commissioning.SetupPayload.DISCOVERY_BLE; + if ("DISCOVERY_ON_NETWORK".equals(name)) return com.codename1.home.commissioning.SetupPayload.DISCOVERY_ON_NETWORK; + if ("DISCOVERY_SOFT_AP".equals(name)) return com.codename1.home.commissioning.SetupPayload.DISCOVERY_SOFT_AP; + throw unsupportedStaticField(com.codename1.home.commissioning.SetupPayload.class, name); + } + + public static Object getField(Object target, String name) throws Exception { + throw unsupportedField(target, name); + } + + public static void setStaticField(Class type, String name, Object value) throws Exception { + throw unsupportedStaticFieldWrite(type, name, value); + } + + public static void setField(Object target, String name, Object value) throws Exception { + throw unsupportedFieldWrite(target, name, value); + } + + private static Object[] safeArgs(Object[] args) { + return args == null ? new Object[0] : args; + } + + private static Object[] adaptArgs(Object[] args, Class[] paramTypes, boolean varArgs) { + if (args == null || args.length == 0) { + return args == null ? new Object[0] : args; + } + Object[] adapted = args.clone(); + if (!varArgs) { + for (int i = 0; i < Math.min(adapted.length, paramTypes.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + return adapted; + } + if (paramTypes.length == 0) { + return adapted; + } + int fixedCount = paramTypes.length - 1; + for (int i = 0; i < Math.min(fixedCount, adapted.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < adapted.length; i++) { + adapted[i] = adaptValue(adapted[i], componentType); + } + return adapted; + } + + private static boolean isSamInterface(Class type) { + if (type == com.codename1.util.OnComplete.class) { + return true; + } + if (type == com.codename1.util.SuccessCallback.class) { + return true; + } + if (type == com.codename1.util.FailureCallback.class) { + return true; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return true; + } + if (type == java.lang.Runnable.class) { + return true; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return true; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return true; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return true; + } + return false; + } + + private static Object adaptLambdaValue(final bsh.cn1.CN1LambdaSupport.LambdaValue lambda, Class type) { + if (type == com.codename1.util.OnComplete.class) { + return new com.codename1.util.OnComplete() { + public void completed(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.SuccessCallback.class) { + return new com.codename1.util.SuccessCallback() { + public void onSucess(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.FailureCallback.class) { + return new com.codename1.util.FailureCallback() { + public void onError(java.lang.Object arg0, java.lang.Throwable arg1, int arg2, java.lang.String arg3) { + try { + lambda.invoke(new Object[]{arg0, arg1, arg2, arg3}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return new com.codename1.ui.events.ActionListener() { + public void actionPerformed(com.codename1.ui.events.ActionEvent arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == java.lang.Runnable.class) { + return new java.lang.Runnable() { + public void run() { + try { + lambda.invoke(new Object[0]); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return new com.codename1.ui.events.DataChangedListener() { + public void dataChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return new com.codename1.ui.events.SelectionListener() { + public void selectionChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return new com.codename1.printing.PrintResultListener() { + public void onResult(com.codename1.printing.PrintResult arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + return lambda; + } + + private static Object adaptValue(Object value, Class type) { + if (!(value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue)) { + return value; + } + // Direct fit when LambdaValue already implements the target SAM + // (Runnable, Function, Comparator, ...). + if (type.isInstance(value)) { + return value; + } + return adaptLambdaValue((bsh.cn1.CN1LambdaSupport.LambdaValue) value, type); + } + + private static int toIntValue(Object value) { + if (value instanceof Number) return ((Number) value).intValue(); + if (value instanceof Character) return (int) ((Character) value).charValue(); + throw new ClassCastException("Cannot coerce " + + (value == null ? "null" : value.getClass().getName()) + " to int"); + } + + private static boolean matches(Object[] args, Class[] paramTypes, boolean varArgs) { + if (!varArgs) { + if (args.length != paramTypes.length) { + return false; + } + for (int i = 0; i < paramTypes.length; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + return true; + } + if (paramTypes.length == 0) { + return true; + } + int fixedCount = paramTypes.length - 1; + if (args.length < fixedCount) { + return false; + } + for (int i = 0; i < fixedCount; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < args.length; i++) { + if (!matchesType(args[i], componentType)) { + return false; + } + } + return true; + } + + private static boolean matchesType(Object value, Class type) { + if (type == Object.class) { + return true; + } + if (value == null) { + return !type.isPrimitive(); + } + if (type.isArray()) { + return type.isInstance(value); + } + if ("boolean".equals(type.getName()) || type == Boolean.class) { + return value instanceof Boolean; + } + if ("char".equals(type.getName()) || type == Character.class) { + return value instanceof Character; + } + if ("byte".equals(type.getName()) || type == Byte.class || "short".equals(type.getName()) || type == Short.class + || "int".equals(type.getName()) || type == Integer.class || "long".equals(type.getName()) || type == Long.class + || "float".equals(type.getName()) || type == Float.class || "double".equals(type.getName()) || type == Double.class) { + // Java widens char to int implicitly, so accept Character + // for any int-or-larger numeric slot. + return value instanceof Number || value instanceof Character; + } + if (value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue) { + // LambdaValue implements common SAMs directly (Runnable, + // Function, Predicate, Comparator, ...). Also accept any + // CN1 SAM the listener-bridge knows how to wrap. + return type.isInstance(value) || isSamInterface(type); + } + return type.isInstance(value); + } + + private static CN1AccessException unsupportedConstruct(Class type, Object[] args) { + return new CN1AccessException("Generated constructor dispatch not implemented for " + type.getName() + describeArgs(args)); + } + + private static CN1AccessException unsupportedStatic(Class type, String name, Object[] args) { + return new CN1AccessException("Generated static dispatch not implemented for " + type.getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedInstance(Object target, String name, Object[] args) { + return new CN1AccessException("Generated instance dispatch not implemented for " + target.getClass().getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedStaticField(Class type, String name) { + return new CN1AccessException("Generated static field access not implemented for " + type.getName() + "." + name); + } + + private static CN1AccessException unsupportedField(Object target, String name) { + return new CN1AccessException("Generated field access not implemented for " + target.getClass().getName() + "." + name); + } + + private static CN1AccessException unsupportedStaticFieldWrite(Class type, String name, Object value) { + return new CN1AccessException("Generated static field write not implemented for " + type.getName() + "." + name + " value=" + describeValue(value)); + } + + private static CN1AccessException unsupportedFieldWrite(Object target, String name, Object value) { + return new CN1AccessException("Generated field write not implemented for " + target.getClass().getName() + "." + name + " value=" + describeValue(value)); + } + + private static String describeArgs(Object[] args) { + if (args == null || args.length == 0) { + return "()"; + } + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < args.length; i++) { + if (i > 0) { + sb.append(", "); + } + sb.append(describeValue(args[i])); + } + sb.append(')'); + return sb.toString(); + } + + private static String describeValue(Object value) { + return value == null ? "null" : value.getClass().getName(); + } +} diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home_spi.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home_spi.java new file mode 100644 index 00000000000..7a97754b885 --- /dev/null +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_home_spi.java @@ -0,0 +1,580 @@ +/* + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ + +package bsh.cn1.gen; + +import bsh.cn1.CN1AccessException; + +public final class GeneratedAccess_com_codename1_home_spi { + private GeneratedAccess_com_codename1_home_spi() { + } + + public static Class findClass(String name) { + if (name == null) { + return null; + } + int dot = name.lastIndexOf('.'); + int dollar = name.lastIndexOf('$'); + int sep = dot > dollar ? dot : dollar; + if (sep < 0 || sep == name.length() - 1) { + return null; + } + return findClassBySimpleName(name.substring(sep + 1)); + } + + public static Class findClassBySimpleName(String simpleName) { + Class found0 = findClassChunk0(simpleName); + if (found0 != null) { + return found0; + } + return null; + } + + + private static Class findClassChunk0(String simpleName) { + if ("HomeBridge".equals(simpleName)) { + return com.codename1.home.spi.HomeBridge.class; + } + return null; + } + public static Object construct(Class type, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + throw unsupportedConstruct(type, safeArgs); + } + + public static Object invokeStatic(Class type, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + throw unsupportedStatic(type, name, safeArgs); + } + + public static Object invoke(Object target, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + CN1AccessException unsupported = null; + if (target instanceof com.codename1.home.spi.HomeBridge) { + try { + return invoke0((com.codename1.home.spi.HomeBridge) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (unsupported != null) { + throw unsupported; + } + throw unsupportedInstance(target, name, safeArgs); + } + + private static Object invoke0(com.codename1.home.spi.HomeBridge typedTarget, String name, Object[] safeArgs) throws Exception { + if ("areIdsPersistent".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.areIdsPersistent(); + } + } + if ("commission".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Integer.class}, false); + typedTarget.commission(toIntValue(adaptedArgs[0]), (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2], (java.lang.String) adaptedArgs[3], (java.lang.String) adaptedArgs[4], toIntValue(adaptedArgs[5])); return null; + } + } + if ("createScene".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String[].class, java.lang.String[].class, java.lang.String[].class, int[].class, double[].class, java.lang.String[].class, int[].class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String[].class, java.lang.String[].class, java.lang.String[].class, int[].class, double[].class, java.lang.String[].class, int[].class}, false); + typedTarget.createScene(toIntValue(adaptedArgs[0]), (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2], (java.lang.String[]) adaptedArgs[3], (java.lang.String[]) adaptedArgs[4], (java.lang.String[]) adaptedArgs[5], (int[]) adaptedArgs[6], (double[]) adaptedArgs[7], (java.lang.String[]) adaptedArgs[8], (int[]) adaptedArgs[9]); return null; + } + } + if ("deleteScene".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class}, false); + typedTarget.deleteScene(toIntValue(adaptedArgs[0]), (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); return null; + } + } + if ("drainChanges".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.drainChanges(toIntValue(adaptedArgs[0])); return null; + } + } + if ("executeScene".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String.class}, false); + typedTarget.executeScene(toIntValue(adaptedArgs[0]), (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); return null; + } + } + if ("getAccessories".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getAccessories((java.lang.String) adaptedArgs[0]); + } + } + if ("getAuthorizationStatus".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAuthorizationStatus(); + } + } + if ("getAvailability".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getAvailability(); + } + } + if ("getBackendId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBackendId(); + } + } + if ("getCommissioningStyle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getCommissioningStyle(); + } + } + if ("getConfigurationProblems".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getConfigurationProblems(); + } + } + if ("getMaxReadBatchSize".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getMaxReadBatchSize(); + } + } + if ("getMaxWriteBatchSize".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getMaxWriteBatchSize(); + } + } + if ("getRooms".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getRooms((java.lang.String) adaptedArgs[0]); + } + } + if ("getSceneActions".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false); + return typedTarget.getSceneActions((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); + } + } + if ("getScenes".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getScenes((java.lang.String) adaptedArgs[0]); + } + } + if ("getServices".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getServices((java.lang.String) adaptedArgs[0]); + } + } + if ("getStructures".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getStructures(); + } + } + if ("getTraits".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false); + return typedTarget.getTraits((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); + } + } + if ("getZones".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getZones((java.lang.String) adaptedArgs[0]); + } + } + if ("identify".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class}, false); + typedTarget.identify(toIntValue(adaptedArgs[0]), (java.lang.String) adaptedArgs[1]); return null; + } + } + if ("isPushDelivery".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isPushDelivery(); + } + } + if ("isSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isSupported(); + } + } + if ("openEcosystemApp".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.openEcosystemApp(); + } + } + if ("openHomeSettings".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.openHomeSettings(); + } + } + if ("openProviderSetup".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.openProviderSetup(); + } + } + if ("readTraits".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String[].class, java.lang.String[].class, java.lang.String[].class, java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String[].class, java.lang.String[].class, java.lang.String[].class, java.lang.Boolean.class}, false); + typedTarget.readTraits(toIntValue(adaptedArgs[0]), (java.lang.String[]) adaptedArgs[1], (java.lang.String[]) adaptedArgs[2], (java.lang.String[]) adaptedArgs[3], ((Boolean) adaptedArgs[4]).booleanValue()); return null; + } + } + if ("refresh".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.refresh(toIntValue(adaptedArgs[0])); return null; + } + } + if ("requestAuthorization".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.requestAuthorization(toIntValue(adaptedArgs[0])); return null; + } + } + if ("start".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.start(toIntValue(adaptedArgs[0])); return null; + } + } + if ("stop".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.stop(); return null; + } + } + if ("subscribe".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String[].class, java.lang.String[].class, java.lang.String[].class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String.class, java.lang.String[].class, java.lang.String[].class, java.lang.String[].class}, false); + typedTarget.subscribe(toIntValue(adaptedArgs[0]), (java.lang.String) adaptedArgs[1], (java.lang.String[]) adaptedArgs[2], (java.lang.String[]) adaptedArgs[3], (java.lang.String[]) adaptedArgs[4]); return null; + } + } + if ("unsubscribe".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.unsubscribe((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("writeTraits".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String[].class, java.lang.String[].class, java.lang.String[].class, int[].class, double[].class, java.lang.String[].class, int[].class, java.lang.String[].class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.String[].class, java.lang.String[].class, java.lang.String[].class, int[].class, double[].class, java.lang.String[].class, int[].class, java.lang.String[].class}, false); + typedTarget.writeTraits(toIntValue(adaptedArgs[0]), (java.lang.String[]) adaptedArgs[1], (java.lang.String[]) adaptedArgs[2], (java.lang.String[]) adaptedArgs[3], (int[]) adaptedArgs[4], (double[]) adaptedArgs[5], (java.lang.String[]) adaptedArgs[6], (int[]) adaptedArgs[7], (java.lang.String[]) adaptedArgs[8]); return null; + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + public static Object getStaticField(Class type, String name) throws Exception { + throw unsupportedStaticField(type, name); + } + + public static Object getField(Object target, String name) throws Exception { + throw unsupportedField(target, name); + } + + public static void setStaticField(Class type, String name, Object value) throws Exception { + throw unsupportedStaticFieldWrite(type, name, value); + } + + public static void setField(Object target, String name, Object value) throws Exception { + throw unsupportedFieldWrite(target, name, value); + } + + private static Object[] safeArgs(Object[] args) { + return args == null ? new Object[0] : args; + } + + private static Object[] adaptArgs(Object[] args, Class[] paramTypes, boolean varArgs) { + if (args == null || args.length == 0) { + return args == null ? new Object[0] : args; + } + Object[] adapted = args.clone(); + if (!varArgs) { + for (int i = 0; i < Math.min(adapted.length, paramTypes.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + return adapted; + } + if (paramTypes.length == 0) { + return adapted; + } + int fixedCount = paramTypes.length - 1; + for (int i = 0; i < Math.min(fixedCount, adapted.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < adapted.length; i++) { + adapted[i] = adaptValue(adapted[i], componentType); + } + return adapted; + } + + private static boolean isSamInterface(Class type) { + if (type == com.codename1.util.OnComplete.class) { + return true; + } + if (type == com.codename1.util.SuccessCallback.class) { + return true; + } + if (type == com.codename1.util.FailureCallback.class) { + return true; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return true; + } + if (type == java.lang.Runnable.class) { + return true; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return true; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return true; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return true; + } + return false; + } + + private static Object adaptLambdaValue(final bsh.cn1.CN1LambdaSupport.LambdaValue lambda, Class type) { + if (type == com.codename1.util.OnComplete.class) { + return new com.codename1.util.OnComplete() { + public void completed(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.SuccessCallback.class) { + return new com.codename1.util.SuccessCallback() { + public void onSucess(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.FailureCallback.class) { + return new com.codename1.util.FailureCallback() { + public void onError(java.lang.Object arg0, java.lang.Throwable arg1, int arg2, java.lang.String arg3) { + try { + lambda.invoke(new Object[]{arg0, arg1, arg2, arg3}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return new com.codename1.ui.events.ActionListener() { + public void actionPerformed(com.codename1.ui.events.ActionEvent arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == java.lang.Runnable.class) { + return new java.lang.Runnable() { + public void run() { + try { + lambda.invoke(new Object[0]); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return new com.codename1.ui.events.DataChangedListener() { + public void dataChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return new com.codename1.ui.events.SelectionListener() { + public void selectionChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return new com.codename1.printing.PrintResultListener() { + public void onResult(com.codename1.printing.PrintResult arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + return lambda; + } + + private static Object adaptValue(Object value, Class type) { + if (!(value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue)) { + return value; + } + // Direct fit when LambdaValue already implements the target SAM + // (Runnable, Function, Comparator, ...). + if (type.isInstance(value)) { + return value; + } + return adaptLambdaValue((bsh.cn1.CN1LambdaSupport.LambdaValue) value, type); + } + + private static int toIntValue(Object value) { + if (value instanceof Number) return ((Number) value).intValue(); + if (value instanceof Character) return (int) ((Character) value).charValue(); + throw new ClassCastException("Cannot coerce " + + (value == null ? "null" : value.getClass().getName()) + " to int"); + } + + private static boolean matches(Object[] args, Class[] paramTypes, boolean varArgs) { + if (!varArgs) { + if (args.length != paramTypes.length) { + return false; + } + for (int i = 0; i < paramTypes.length; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + return true; + } + if (paramTypes.length == 0) { + return true; + } + int fixedCount = paramTypes.length - 1; + if (args.length < fixedCount) { + return false; + } + for (int i = 0; i < fixedCount; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < args.length; i++) { + if (!matchesType(args[i], componentType)) { + return false; + } + } + return true; + } + + private static boolean matchesType(Object value, Class type) { + if (type == Object.class) { + return true; + } + if (value == null) { + return !type.isPrimitive(); + } + if (type.isArray()) { + return type.isInstance(value); + } + if ("boolean".equals(type.getName()) || type == Boolean.class) { + return value instanceof Boolean; + } + if ("char".equals(type.getName()) || type == Character.class) { + return value instanceof Character; + } + if ("byte".equals(type.getName()) || type == Byte.class || "short".equals(type.getName()) || type == Short.class + || "int".equals(type.getName()) || type == Integer.class || "long".equals(type.getName()) || type == Long.class + || "float".equals(type.getName()) || type == Float.class || "double".equals(type.getName()) || type == Double.class) { + // Java widens char to int implicitly, so accept Character + // for any int-or-larger numeric slot. + return value instanceof Number || value instanceof Character; + } + if (value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue) { + // LambdaValue implements common SAMs directly (Runnable, + // Function, Predicate, Comparator, ...). Also accept any + // CN1 SAM the listener-bridge knows how to wrap. + return type.isInstance(value) || isSamInterface(type); + } + return type.isInstance(value); + } + + private static CN1AccessException unsupportedConstruct(Class type, Object[] args) { + return new CN1AccessException("Generated constructor dispatch not implemented for " + type.getName() + describeArgs(args)); + } + + private static CN1AccessException unsupportedStatic(Class type, String name, Object[] args) { + return new CN1AccessException("Generated static dispatch not implemented for " + type.getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedInstance(Object target, String name, Object[] args) { + return new CN1AccessException("Generated instance dispatch not implemented for " + target.getClass().getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedStaticField(Class type, String name) { + return new CN1AccessException("Generated static field access not implemented for " + type.getName() + "." + name); + } + + private static CN1AccessException unsupportedField(Object target, String name) { + return new CN1AccessException("Generated field access not implemented for " + target.getClass().getName() + "." + name); + } + + private static CN1AccessException unsupportedStaticFieldWrite(Class type, String name, Object value) { + return new CN1AccessException("Generated static field write not implemented for " + type.getName() + "." + name + " value=" + describeValue(value)); + } + + private static CN1AccessException unsupportedFieldWrite(Object target, String name, Object value) { + return new CN1AccessException("Generated field write not implemented for " + target.getClass().getName() + "." + name + " value=" + describeValue(value)); + } + + private static String describeArgs(Object[] args) { + if (args == null || args.length == 0) { + return "()"; + } + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < args.length; i++) { + if (i > 0) { + sb.append(", "); + } + sb.append(describeValue(args[i])); + } + sb.append(')'); + return sb.toString(); + } + + private static String describeValue(Object value) { + return value == null ? "null" : value.getClass().getName(); + } +} diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_intents.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_intents.java new file mode 100644 index 00000000000..64145d54a8f --- /dev/null +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_intents.java @@ -0,0 +1,1168 @@ +/* + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ + +package bsh.cn1.gen; + +import bsh.cn1.CN1AccessException; + +public final class GeneratedAccess_com_codename1_intents { + private GeneratedAccess_com_codename1_intents() { + } + + public static Class findClass(String name) { + if (name == null) { + return null; + } + int dot = name.lastIndexOf('.'); + int dollar = name.lastIndexOf('$'); + int sep = dot > dollar ? dot : dollar; + if (sep < 0 || sep == name.length() - 1) { + return null; + } + return findClassBySimpleName(name.substring(sep + 1)); + } + + public static Class findClassBySimpleName(String simpleName) { + Class found0 = findClassChunk0(simpleName); + if (found0 != null) { + return found0; + } + return null; + } + + + private static Class findClassChunk0(String simpleName) { + if ("AppEntity".equals(simpleName)) { + return com.codename1.intents.AppEntity.class; + } + if ("DynamicIntent".equals(simpleName)) { + return com.codename1.intents.DynamicIntent.class; + } + if ("EntitySelectionHandler".equals(simpleName)) { + return com.codename1.intents.EntitySelectionHandler.class; + } + if ("Exposure".equals(simpleName)) { + return com.codename1.intents.Exposure.class; + } + if ("IntentCompletion".equals(simpleName)) { + return com.codename1.intents.IntentCompletion.class; + } + if ("IntentContext".equals(simpleName)) { + return com.codename1.intents.IntentContext.class; + } + if ("IntentDates".equals(simpleName)) { + return com.codename1.intents.IntentDates.class; + } + if ("IntentDeclaration".equals(simpleName)) { + return com.codename1.intents.IntentDeclaration.class; + } + if ("IntentDispatcher".equals(simpleName)) { + return com.codename1.intents.IntentDispatcher.class; + } + if ("IntentParameterInfo".equals(simpleName)) { + return com.codename1.intents.IntentParameterInfo.class; + } + if ("IntentParameterType".equals(simpleName)) { + return com.codename1.intents.IntentParameterType.class; + } + if ("IntentResult".equals(simpleName)) { + return com.codename1.intents.IntentResult.class; + } + if ("IntentSerializer".equals(simpleName)) { + return com.codename1.intents.IntentSerializer.class; + } + if ("IntentSource".equals(simpleName)) { + return com.codename1.intents.IntentSource.class; + } + if ("Intents".equals(simpleName)) { + return com.codename1.intents.Intents.class; + } + return null; + } + public static Object construct(Class type, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + if (type == com.codename1.intents.AppEntity.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false); + return new com.codename1.intents.AppEntity((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); + } + } + if (type == com.codename1.intents.DynamicIntent.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class}, false); + return new com.codename1.intents.DynamicIntent((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); + } + } + if (type == com.codename1.intents.IntentContext.class) { + if (matches(safeArgs, new Class[]{com.codename1.intents.IntentSource.class, java.lang.Boolean.class, java.lang.Long.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.intents.IntentSource.class, java.lang.Boolean.class, java.lang.Long.class}, false); + return new com.codename1.intents.IntentContext((com.codename1.intents.IntentSource) adaptedArgs[0], ((Boolean) adaptedArgs[1]).booleanValue(), ((Number) adaptedArgs[2]).longValue()); + } + } + if (type == com.codename1.intents.IntentDeclaration.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.String.class, java.lang.Integer.class, java.util.List.class, java.util.List.class, java.util.List.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.String.class, java.lang.Integer.class, java.util.List.class, java.util.List.class, java.util.List.class}, false); + return new com.codename1.intents.IntentDeclaration((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2], ((Boolean) adaptedArgs[3]).booleanValue(), ((Boolean) adaptedArgs[4]).booleanValue(), ((Boolean) adaptedArgs[5]).booleanValue(), (java.lang.String) adaptedArgs[6], toIntValue(adaptedArgs[7]), (java.util.List) adaptedArgs[8], (java.util.List) adaptedArgs[9], (java.util.List) adaptedArgs[10]); + } + } + if (type == com.codename1.intents.IntentParameterInfo.class) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.intents.IntentParameterType.class, java.lang.Boolean.class, java.lang.String.class, java.lang.String.class, java.util.List.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.intents.IntentParameterType.class, java.lang.Boolean.class, java.lang.String.class, java.lang.String.class, java.util.List.class}, false); + return new com.codename1.intents.IntentParameterInfo((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (com.codename1.intents.IntentParameterType) adaptedArgs[2], ((Boolean) adaptedArgs[3]).booleanValue(), (java.lang.String) adaptedArgs[4], (java.lang.String) adaptedArgs[5], (java.util.List) adaptedArgs[6]); + } + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.intents.IntentParameterType.class, java.lang.Boolean.class, java.lang.String.class, java.lang.String.class, java.util.List.class, java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, com.codename1.intents.IntentParameterType.class, java.lang.Boolean.class, java.lang.String.class, java.lang.String.class, java.util.List.class, java.lang.Integer.class}, false); + return new com.codename1.intents.IntentParameterInfo((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (com.codename1.intents.IntentParameterType) adaptedArgs[2], ((Boolean) adaptedArgs[3]).booleanValue(), (java.lang.String) adaptedArgs[4], (java.lang.String) adaptedArgs[5], (java.util.List) adaptedArgs[6], toIntValue(adaptedArgs[7])); + } + } + throw unsupportedConstruct(type, safeArgs); + } + + public static Object invokeStatic(Class type, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + if (type == com.codename1.intents.IntentDates.class) return invokeStatic0(name, safeArgs); + if (type == com.codename1.intents.IntentResult.class) return invokeStatic1(name, safeArgs); + if (type == com.codename1.intents.IntentSerializer.class) return invokeStatic2(name, safeArgs); + if (type == com.codename1.intents.Intents.class) return invokeStatic3(name, safeArgs); + throw unsupportedStatic(type, name, safeArgs); + } + + private static Object invokeStatic0(String name, Object[] safeArgs) throws Exception { + if ("parse".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Object.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Object.class}, false); + return com.codename1.intents.IntentDates.parse((java.lang.Object) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.intents.IntentDates.class, name, safeArgs); + } + + private static Object invokeStatic1(String name, Object[] safeArgs) throws Exception { + if ("entity".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.intents.AppEntity.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.intents.AppEntity.class}, false); + return com.codename1.intents.IntentResult.entity((com.codename1.intents.AppEntity) adaptedArgs[0]); + } + } + if ("failed".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.intents.IntentResult.failed((java.lang.String) adaptedArgs[0]); + } + } + if ("ok".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.intents.IntentResult.ok(); + } + } + if ("opens".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.intents.IntentResult.opens((java.lang.String) adaptedArgs[0]); + } + } + if ("spoken".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.intents.IntentResult.spoken((java.lang.String) adaptedArgs[0]); + } + } + if ("value".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Object.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Object.class}, false); + return com.codename1.intents.IntentResult.value((java.lang.Object) adaptedArgs[0]); + } + } + throw unsupportedStatic(com.codename1.intents.IntentResult.class, name, safeArgs); + } + + private static Object invokeStatic2(String name, Object[] safeArgs) throws Exception { + if ("mergeParams".equals(name)) { + if (matches(safeArgs, new Class[]{java.util.Map.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.util.Map.class, java.lang.String.class}, false); + return com.codename1.intents.IntentSerializer.mergeParams((java.util.Map) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); + } + } + if ("parsePayload".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.intents.IntentSerializer.parsePayload((java.lang.String) adaptedArgs[0]); + } + } + if ("serializeDeclarations".equals(name)) { + if (matches(safeArgs, new Class[]{java.util.List.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.util.List.class}, false); + return com.codename1.intents.IntentSerializer.serializeDeclarations((java.util.List) adaptedArgs[0]); + } + } + if ("serializeEntities".equals(name)) { + if (matches(safeArgs, new Class[]{java.util.List.class, java.util.Map.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.util.List.class, java.util.Map.class}, false); + return com.codename1.intents.IntentSerializer.serializeEntities((java.util.List) adaptedArgs[0], (java.util.Map) adaptedArgs[1]); + } + if (matches(safeArgs, new Class[]{java.util.List.class, java.util.Map.class, java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.util.List.class, java.util.Map.class, java.lang.Boolean.class}, false); + return com.codename1.intents.IntentSerializer.serializeEntities((java.util.List) adaptedArgs[0], (java.util.Map) adaptedArgs[1], ((Boolean) adaptedArgs[2]).booleanValue()); + } + } + if ("serializeEntityRef".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false); + return com.codename1.intents.IntentSerializer.serializeEntityRef((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); + } + } + if ("serializeParams".equals(name)) { + if (matches(safeArgs, new Class[]{java.util.Map.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.util.Map.class}, false); + return com.codename1.intents.IntentSerializer.serializeParams((java.util.Map) adaptedArgs[0]); + } + } + if ("serializeResult".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.intents.IntentResult.class, java.util.Map.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.intents.IntentResult.class, java.util.Map.class}, false); + return com.codename1.intents.IntentSerializer.serializeResult((com.codename1.intents.IntentResult) adaptedArgs[0], (java.util.Map) adaptedArgs[1]); + } + } + throw unsupportedStatic(com.codename1.intents.IntentSerializer.class, name, safeArgs); + } + + private static Object invokeStatic3(String name, Object[] safeArgs) throws Exception { + if ("areIntentsSupported".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.intents.Intents.areIntentsSupported(); + } + } + if ("asTools".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.intents.Intents.asTools(); + } + } + if ("clearIndex".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + com.codename1.intents.Intents.clearIndex((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("dispatchInvocation".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class, com.codename1.intents.IntentSource.class, java.lang.Boolean.class, com.codename1.intents.IntentCompletion.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class, com.codename1.intents.IntentSource.class, java.lang.Boolean.class, com.codename1.intents.IntentCompletion.class}, false); + com.codename1.intents.Intents.dispatchInvocation((java.lang.String) adaptedArgs[0], (java.util.Map) adaptedArgs[1], (com.codename1.intents.IntentSource) adaptedArgs[2], ((Boolean) adaptedArgs[3]).booleanValue(), (com.codename1.intents.IntentCompletion) adaptedArgs[4]); return null; + } + } + if ("dispatchSpotlightSelection".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + com.codename1.intents.Intents.dispatchSpotlightSelection((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("dispatchUserActivity".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class}, false); + return com.codename1.intents.Intents.dispatchUserActivity((java.lang.String) adaptedArgs[0], (java.util.Map) adaptedArgs[1]); + } + } + if ("donate".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class}, false); + com.codename1.intents.Intents.donate((java.lang.String) adaptedArgs[0], (java.util.Map) adaptedArgs[1]); return null; + } + } + if ("getDeclaration".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.intents.Intents.getDeclaration((java.lang.String) adaptedArgs[0]); + } + } + if ("getDeclarations".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.intents.Intents.getDeclarations(); + } + } + if ("getDefaultTimeout".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.intents.Intents.getDefaultTimeout(); + } + } + if ("getDynamicIntent".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return com.codename1.intents.Intents.getDynamicIntent((java.lang.String) adaptedArgs[0]); + } + } + if ("index".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.intents.AppEntity.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.intents.AppEntity.class}, false); + com.codename1.intents.Intents.index((com.codename1.intents.AppEntity) adaptedArgs[0]); return null; + } + if (matches(safeArgs, new Class[]{java.util.List.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.util.List.class}, false); + com.codename1.intents.Intents.index((java.util.List) adaptedArgs[0]); return null; + } + } + if ("invoke".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class}, false); + return com.codename1.intents.Intents.invoke((java.lang.String) adaptedArgs[0], (java.util.Map) adaptedArgs[1]); + } + } + if ("isHeadlessExecutionSupported".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.intents.Intents.isHeadlessExecutionSupported(); + } + } + if ("isIndexingSupported".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.intents.Intents.isIndexingSupported(); + } + } + if ("isVoiceInvocationSupported".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.intents.Intents.isVoiceInvocationSupported(); + } + } + if ("publishPendingDeclarations".equals(name)) { + if (safeArgs.length == 0) { + com.codename1.intents.Intents.publishPendingDeclarations(); return null; + } + } + if ("queryEntities".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class}, false); + return com.codename1.intents.Intents.queryEntities((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); + } + } + if ("registerDynamicIntent".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.intents.DynamicIntent.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.intents.DynamicIntent.class}, false); + com.codename1.intents.Intents.registerDynamicIntent((com.codename1.intents.DynamicIntent) adaptedArgs[0]); return null; + } + } + if ("removeFromIndex".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false); + com.codename1.intents.Intents.removeFromIndex((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); return null; + } + } + if ("setBridge".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.intents.spi.IntentBridge.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.intents.spi.IntentBridge.class}, false); + com.codename1.intents.Intents.setBridge((com.codename1.intents.spi.IntentBridge) adaptedArgs[0]); return null; + } + } + if ("setDefaultTimeout".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + com.codename1.intents.Intents.setDefaultTimeout(toIntValue(adaptedArgs[0])); return null; + } + } + if ("setDispatcher".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.intents.IntentDispatcher.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.intents.IntentDispatcher.class}, false); + com.codename1.intents.Intents.setDispatcher((com.codename1.intents.IntentDispatcher) adaptedArgs[0]); return null; + } + } + if ("setSelectionHandler".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.intents.EntitySelectionHandler.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.intents.EntitySelectionHandler.class}, false); + com.codename1.intents.Intents.setSelectionHandler((com.codename1.intents.EntitySelectionHandler) adaptedArgs[0]); return null; + } + } + throw unsupportedStatic(com.codename1.intents.Intents.class, name, safeArgs); + } + + public static Object invoke(Object target, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + CN1AccessException unsupported = null; + if (target instanceof com.codename1.intents.AppEntity) { + try { + return invoke0((com.codename1.intents.AppEntity) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.intents.DynamicIntent) { + try { + return invoke1((com.codename1.intents.DynamicIntent) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.intents.IntentContext) { + try { + return invoke2((com.codename1.intents.IntentContext) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.intents.IntentDeclaration) { + try { + return invoke3((com.codename1.intents.IntentDeclaration) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.intents.IntentParameterInfo) { + try { + return invoke4((com.codename1.intents.IntentParameterInfo) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.intents.IntentResult) { + try { + return invoke5((com.codename1.intents.IntentResult) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.intents.EntitySelectionHandler) { + try { + return invoke6((com.codename1.intents.EntitySelectionHandler) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.intents.IntentCompletion) { + try { + return invoke7((com.codename1.intents.IntentCompletion) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (target instanceof com.codename1.intents.IntentDispatcher) { + try { + return invoke8((com.codename1.intents.IntentDispatcher) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (unsupported != null) { + throw unsupported; + } + throw unsupportedInstance(target, name, safeArgs); + } + + private static Object invoke0(com.codename1.intents.AppEntity typedTarget, String name, Object[] safeArgs) throws Exception { + if ("addKeywords".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String[].class}, true)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String[].class}, true); + java.lang.String[] varArgs = new java.lang.String[adaptedArgs.length - 0]; + for (int i = 0; i < adaptedArgs.length; i++) { + varArgs[i - 0] = (java.lang.String) adaptedArgs[i]; + } + return typedTarget.addKeywords(varArgs); + } + } + if ("getId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getId(); + } + } + if ("getImage".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getImage(); + } + } + if ("getKeywords".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getKeywords(); + } + } + if ("getSubtitle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSubtitle(); + } + } + if ("getTitle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTitle(); + } + } + if ("getType".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getType(); + } + } + if ("setImage".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.EncodedImage.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.EncodedImage.class}, false); + return typedTarget.setImage((com.codename1.ui.EncodedImage) adaptedArgs[0]); + } + } + if ("setSubtitle".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.setSubtitle((java.lang.String) adaptedArgs[0]); + } + } + if ("setTitle".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.setTitle((java.lang.String) adaptedArgs[0]); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke1(com.codename1.intents.DynamicIntent typedTarget, String name, Object[] safeArgs) throws Exception { + if ("bind".equals(name)) { + if (matches(safeArgs, new Class[]{java.util.Map.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.util.Map.class}, false); + return typedTarget.bind((java.util.Map) adaptedArgs[0]); + } + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Object.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Object.class}, false); + return typedTarget.bind((java.lang.String) adaptedArgs[0], (java.lang.Object) adaptedArgs[1]); + } + } + if ("getBaseIntentId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBaseIntentId(); + } + } + if ("getBoundParameters".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getBoundParameters(); + } + } + if ("getId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getId(); + } + } + if ("getTitle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTitle(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke2(com.codename1.intents.IntentContext typedTarget, String name, Object[] safeArgs) throws Exception { + if ("cancel".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.cancel(); return null; + } + } + if ("getDeadline".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDeadline(); + } + } + if ("getRemainingTime".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getRemainingTime(); + } + } + if ("getSource".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSource(); + } + } + if ("isCancelled".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isCancelled(); + } + } + if ("isHeadless".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isHeadless(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke3(com.codename1.intents.IntentDeclaration typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getDescription".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDescription(); + } + } + if ("getExposure".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getExposure(); + } + } + if ("getId".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getId(); + } + } + if ("getOpensRoute".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getOpensRoute(); + } + } + if ("getParameter".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.getParameter((java.lang.String) adaptedArgs[0]); + } + } + if ("getParameters".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getParameters(); + } + } + if ("getPhrases".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getPhrases(); + } + } + if ("getTimeoutSeconds".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTimeoutSeconds(); + } + } + if ("getTitle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTitle(); + } + } + if ("isDestructive".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isDestructive(); + } + } + if ("isDiscoverable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isDiscoverable(); + } + } + if ("isExposedTo".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.intents.Exposure.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.intents.Exposure.class}, false); + return typedTarget.isExposedTo((com.codename1.intents.Exposure) adaptedArgs[0]); + } + } + if ("isHeadless".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isHeadless(); + } + } + if ("runsHeadless".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.runsHeadless(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke4(com.codename1.intents.IntentParameterInfo typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getDefaultValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDefaultValue(); + } + } + if ("getEntityType".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getEntityType(); + } + } + if ("getName".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getName(); + } + } + if ("getNumericWidthBits".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getNumericWidthBits(); + } + } + if ("getOptions".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getOptions(); + } + } + if ("getTitle".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTitle(); + } + } + if ("getType".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getType(); + } + } + if ("isRequired".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isRequired(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke5(com.codename1.intents.IntentResult typedTarget, String name, Object[] safeArgs) throws Exception { + if ("getDialog".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getDialog(); + } + } + if ("getEntity".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getEntity(); + } + } + if ("getErrorMessage".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getErrorMessage(); + } + } + if ("getOpenUrl".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getOpenUrl(); + } + } + if ("getSnippet".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getSnippet(); + } + } + if ("getValue".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getValue(); + } + } + if ("isFailed".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isFailed(); + } + } + if ("toString".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.toString(); + } + } + if ("withDialog".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.withDialog((java.lang.String) adaptedArgs[0]); + } + } + if ("withOpenUrl".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.withOpenUrl((java.lang.String) adaptedArgs[0]); + } + } + if ("withSnippet".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.surfaces.SurfaceNode.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.surfaces.SurfaceNode.class}, false); + return typedTarget.withSnippet((com.codename1.surfaces.SurfaceNode) adaptedArgs[0]); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke6(com.codename1.intents.EntitySelectionHandler typedTarget, String name, Object[] safeArgs) throws Exception { + if ("onEntitySelected".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.intents.AppEntity.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.intents.AppEntity.class}, false); + typedTarget.onEntitySelected((com.codename1.intents.AppEntity) adaptedArgs[0]); return null; + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke7(com.codename1.intents.IntentCompletion typedTarget, String name, Object[] safeArgs) throws Exception { + if ("onIntentResult".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.intents.IntentResult.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.intents.IntentResult.class}, false); + typedTarget.onIntentResult((com.codename1.intents.IntentResult) adaptedArgs[0]); return null; + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke8(com.codename1.intents.IntentDispatcher typedTarget, String name, Object[] safeArgs) throws Exception { + if ("describe".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.describe(); + } + } + if ("invoke".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class, com.codename1.intents.IntentContext.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class, com.codename1.intents.IntentContext.class}, false); + return typedTarget.invoke((java.lang.String) adaptedArgs[0], (java.util.Map) adaptedArgs[1], (com.codename1.intents.IntentContext) adaptedArgs[2]); + } + } + if ("queryEntities".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.lang.String.class}, false); + return typedTarget.queryEntities((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + public static Object getStaticField(Class type, String name) throws Exception { + if (type == com.codename1.intents.Exposure.class) return getStaticField0(name); + if (type == com.codename1.intents.IntentParameterType.class) return getStaticField1(name); + if (type == com.codename1.intents.IntentSource.class) return getStaticField2(name); + throw unsupportedStaticField(type, name); + } + + private static Object getStaticField0(String name) throws Exception { + if ("ASSISTANT".equals(name)) return com.codename1.intents.Exposure.ASSISTANT; + if ("MODEL".equals(name)) return com.codename1.intents.Exposure.MODEL; + throw unsupportedStaticField(com.codename1.intents.Exposure.class, name); + } + + private static Object getStaticField1(String name) throws Exception { + if ("BOOLEAN".equals(name)) return com.codename1.intents.IntentParameterType.BOOLEAN; + if ("DATE".equals(name)) return com.codename1.intents.IntentParameterType.DATE; + if ("ENTITY".equals(name)) return com.codename1.intents.IntentParameterType.ENTITY; + if ("INTEGER".equals(name)) return com.codename1.intents.IntentParameterType.INTEGER; + if ("NUMBER".equals(name)) return com.codename1.intents.IntentParameterType.NUMBER; + if ("STRING".equals(name)) return com.codename1.intents.IntentParameterType.STRING; + throw unsupportedStaticField(com.codename1.intents.IntentParameterType.class, name); + } + + private static Object getStaticField2(String name) throws Exception { + if ("IN_APP".equals(name)) return com.codename1.intents.IntentSource.IN_APP; + if ("MODEL".equals(name)) return com.codename1.intents.IntentSource.MODEL; + if ("SHORTCUT".equals(name)) return com.codename1.intents.IntentSource.SHORTCUT; + if ("SPOTLIGHT".equals(name)) return com.codename1.intents.IntentSource.SPOTLIGHT; + if ("UNKNOWN".equals(name)) return com.codename1.intents.IntentSource.UNKNOWN; + if ("VOICE".equals(name)) return com.codename1.intents.IntentSource.VOICE; + if ("WIDGET".equals(name)) return com.codename1.intents.IntentSource.WIDGET; + throw unsupportedStaticField(com.codename1.intents.IntentSource.class, name); + } + + public static Object getField(Object target, String name) throws Exception { + throw unsupportedField(target, name); + } + + public static void setStaticField(Class type, String name, Object value) throws Exception { + throw unsupportedStaticFieldWrite(type, name, value); + } + + public static void setField(Object target, String name, Object value) throws Exception { + throw unsupportedFieldWrite(target, name, value); + } + + private static Object[] safeArgs(Object[] args) { + return args == null ? new Object[0] : args; + } + + private static Object[] adaptArgs(Object[] args, Class[] paramTypes, boolean varArgs) { + if (args == null || args.length == 0) { + return args == null ? new Object[0] : args; + } + Object[] adapted = args.clone(); + if (!varArgs) { + for (int i = 0; i < Math.min(adapted.length, paramTypes.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + return adapted; + } + if (paramTypes.length == 0) { + return adapted; + } + int fixedCount = paramTypes.length - 1; + for (int i = 0; i < Math.min(fixedCount, adapted.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < adapted.length; i++) { + adapted[i] = adaptValue(adapted[i], componentType); + } + return adapted; + } + + private static boolean isSamInterface(Class type) { + if (type == com.codename1.util.OnComplete.class) { + return true; + } + if (type == com.codename1.util.SuccessCallback.class) { + return true; + } + if (type == com.codename1.util.FailureCallback.class) { + return true; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return true; + } + if (type == java.lang.Runnable.class) { + return true; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return true; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return true; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return true; + } + return false; + } + + private static Object adaptLambdaValue(final bsh.cn1.CN1LambdaSupport.LambdaValue lambda, Class type) { + if (type == com.codename1.util.OnComplete.class) { + return new com.codename1.util.OnComplete() { + public void completed(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.SuccessCallback.class) { + return new com.codename1.util.SuccessCallback() { + public void onSucess(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.FailureCallback.class) { + return new com.codename1.util.FailureCallback() { + public void onError(java.lang.Object arg0, java.lang.Throwable arg1, int arg2, java.lang.String arg3) { + try { + lambda.invoke(new Object[]{arg0, arg1, arg2, arg3}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return new com.codename1.ui.events.ActionListener() { + public void actionPerformed(com.codename1.ui.events.ActionEvent arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == java.lang.Runnable.class) { + return new java.lang.Runnable() { + public void run() { + try { + lambda.invoke(new Object[0]); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return new com.codename1.ui.events.DataChangedListener() { + public void dataChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return new com.codename1.ui.events.SelectionListener() { + public void selectionChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return new com.codename1.printing.PrintResultListener() { + public void onResult(com.codename1.printing.PrintResult arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + return lambda; + } + + private static Object adaptValue(Object value, Class type) { + if (!(value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue)) { + return value; + } + // Direct fit when LambdaValue already implements the target SAM + // (Runnable, Function, Comparator, ...). + if (type.isInstance(value)) { + return value; + } + return adaptLambdaValue((bsh.cn1.CN1LambdaSupport.LambdaValue) value, type); + } + + private static int toIntValue(Object value) { + if (value instanceof Number) return ((Number) value).intValue(); + if (value instanceof Character) return (int) ((Character) value).charValue(); + throw new ClassCastException("Cannot coerce " + + (value == null ? "null" : value.getClass().getName()) + " to int"); + } + + private static boolean matches(Object[] args, Class[] paramTypes, boolean varArgs) { + if (!varArgs) { + if (args.length != paramTypes.length) { + return false; + } + for (int i = 0; i < paramTypes.length; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + return true; + } + if (paramTypes.length == 0) { + return true; + } + int fixedCount = paramTypes.length - 1; + if (args.length < fixedCount) { + return false; + } + for (int i = 0; i < fixedCount; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < args.length; i++) { + if (!matchesType(args[i], componentType)) { + return false; + } + } + return true; + } + + private static boolean matchesType(Object value, Class type) { + if (type == Object.class) { + return true; + } + if (value == null) { + return !type.isPrimitive(); + } + if (type.isArray()) { + return type.isInstance(value); + } + if ("boolean".equals(type.getName()) || type == Boolean.class) { + return value instanceof Boolean; + } + if ("char".equals(type.getName()) || type == Character.class) { + return value instanceof Character; + } + if ("byte".equals(type.getName()) || type == Byte.class || "short".equals(type.getName()) || type == Short.class + || "int".equals(type.getName()) || type == Integer.class || "long".equals(type.getName()) || type == Long.class + || "float".equals(type.getName()) || type == Float.class || "double".equals(type.getName()) || type == Double.class) { + // Java widens char to int implicitly, so accept Character + // for any int-or-larger numeric slot. + return value instanceof Number || value instanceof Character; + } + if (value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue) { + // LambdaValue implements common SAMs directly (Runnable, + // Function, Predicate, Comparator, ...). Also accept any + // CN1 SAM the listener-bridge knows how to wrap. + return type.isInstance(value) || isSamInterface(type); + } + return type.isInstance(value); + } + + private static CN1AccessException unsupportedConstruct(Class type, Object[] args) { + return new CN1AccessException("Generated constructor dispatch not implemented for " + type.getName() + describeArgs(args)); + } + + private static CN1AccessException unsupportedStatic(Class type, String name, Object[] args) { + return new CN1AccessException("Generated static dispatch not implemented for " + type.getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedInstance(Object target, String name, Object[] args) { + return new CN1AccessException("Generated instance dispatch not implemented for " + target.getClass().getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedStaticField(Class type, String name) { + return new CN1AccessException("Generated static field access not implemented for " + type.getName() + "." + name); + } + + private static CN1AccessException unsupportedField(Object target, String name) { + return new CN1AccessException("Generated field access not implemented for " + target.getClass().getName() + "." + name); + } + + private static CN1AccessException unsupportedStaticFieldWrite(Class type, String name, Object value) { + return new CN1AccessException("Generated static field write not implemented for " + type.getName() + "." + name + " value=" + describeValue(value)); + } + + private static CN1AccessException unsupportedFieldWrite(Object target, String name, Object value) { + return new CN1AccessException("Generated field write not implemented for " + target.getClass().getName() + "." + name + " value=" + describeValue(value)); + } + + private static String describeArgs(Object[] args) { + if (args == null || args.length == 0) { + return "()"; + } + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < args.length; i++) { + if (i > 0) { + sb.append(", "); + } + sb.append(describeValue(args[i])); + } + sb.append(')'); + return sb.toString(); + } + + private static String describeValue(Object value) { + return value == null ? "null" : value.getClass().getName(); + } +} diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_intents_spi.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_intents_spi.java new file mode 100644 index 00000000000..2e8a929336f --- /dev/null +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_intents_spi.java @@ -0,0 +1,446 @@ +/* + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ + +package bsh.cn1.gen; + +import bsh.cn1.CN1AccessException; + +public final class GeneratedAccess_com_codename1_intents_spi { + private GeneratedAccess_com_codename1_intents_spi() { + } + + public static Class findClass(String name) { + if (name == null) { + return null; + } + int dot = name.lastIndexOf('.'); + int dollar = name.lastIndexOf('$'); + int sep = dot > dollar ? dot : dollar; + if (sep < 0 || sep == name.length() - 1) { + return null; + } + return findClassBySimpleName(name.substring(sep + 1)); + } + + public static Class findClassBySimpleName(String simpleName) { + Class found0 = findClassChunk0(simpleName); + if (found0 != null) { + return found0; + } + return null; + } + + + private static Class findClassChunk0(String simpleName) { + if ("IntentBridge".equals(simpleName)) { + return com.codename1.intents.spi.IntentBridge.class; + } + return null; + } + public static Object construct(Class type, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + throw unsupportedConstruct(type, safeArgs); + } + + public static Object invokeStatic(Class type, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + throw unsupportedStatic(type, name, safeArgs); + } + + public static Object invoke(Object target, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + CN1AccessException unsupported = null; + if (target instanceof com.codename1.intents.spi.IntentBridge) { + try { + return invoke0((com.codename1.intents.spi.IntentBridge) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } + if (unsupported != null) { + throw unsupported; + } + throw unsupportedInstance(target, name, safeArgs); + } + + private static Object invoke0(com.codename1.intents.spi.IntentBridge typedTarget, String name, Object[] safeArgs) throws Exception { + if ("areIntentsSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.areIntentsSupported(); + } + } + if ("clearIndex".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.clearIndex((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("completeInvocation".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.util.Map.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, java.util.Map.class}, false); + typedTarget.completeInvocation((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.util.Map) adaptedArgs[2]); return null; + } + } + if ("donate".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false); + typedTarget.donate((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); return null; + } + } + if ("index".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.util.Map.class}, false); + typedTarget.index((java.lang.String) adaptedArgs[0], (java.util.Map) adaptedArgs[1]); return null; + } + } + if ("isHeadlessExecutionSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isHeadlessExecutionSupported(); + } + } + if ("isIndexingSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isIndexingSupported(); + } + } + if ("isVoiceInvocationSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isVoiceInvocationSupported(); + } + } + if ("registerIntents".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.registerIntents((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("removeFromIndex".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.removeFromIndex((java.lang.String) adaptedArgs[0]); return null; + } + } + if ("requestForeground".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.requestForeground(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + public static Object getStaticField(Class type, String name) throws Exception { + throw unsupportedStaticField(type, name); + } + + public static Object getField(Object target, String name) throws Exception { + throw unsupportedField(target, name); + } + + public static void setStaticField(Class type, String name, Object value) throws Exception { + throw unsupportedStaticFieldWrite(type, name, value); + } + + public static void setField(Object target, String name, Object value) throws Exception { + throw unsupportedFieldWrite(target, name, value); + } + + private static Object[] safeArgs(Object[] args) { + return args == null ? new Object[0] : args; + } + + private static Object[] adaptArgs(Object[] args, Class[] paramTypes, boolean varArgs) { + if (args == null || args.length == 0) { + return args == null ? new Object[0] : args; + } + Object[] adapted = args.clone(); + if (!varArgs) { + for (int i = 0; i < Math.min(adapted.length, paramTypes.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + return adapted; + } + if (paramTypes.length == 0) { + return adapted; + } + int fixedCount = paramTypes.length - 1; + for (int i = 0; i < Math.min(fixedCount, adapted.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < adapted.length; i++) { + adapted[i] = adaptValue(adapted[i], componentType); + } + return adapted; + } + + private static boolean isSamInterface(Class type) { + if (type == com.codename1.util.OnComplete.class) { + return true; + } + if (type == com.codename1.util.SuccessCallback.class) { + return true; + } + if (type == com.codename1.util.FailureCallback.class) { + return true; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return true; + } + if (type == java.lang.Runnable.class) { + return true; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return true; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return true; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return true; + } + return false; + } + + private static Object adaptLambdaValue(final bsh.cn1.CN1LambdaSupport.LambdaValue lambda, Class type) { + if (type == com.codename1.util.OnComplete.class) { + return new com.codename1.util.OnComplete() { + public void completed(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.SuccessCallback.class) { + return new com.codename1.util.SuccessCallback() { + public void onSucess(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.FailureCallback.class) { + return new com.codename1.util.FailureCallback() { + public void onError(java.lang.Object arg0, java.lang.Throwable arg1, int arg2, java.lang.String arg3) { + try { + lambda.invoke(new Object[]{arg0, arg1, arg2, arg3}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return new com.codename1.ui.events.ActionListener() { + public void actionPerformed(com.codename1.ui.events.ActionEvent arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == java.lang.Runnable.class) { + return new java.lang.Runnable() { + public void run() { + try { + lambda.invoke(new Object[0]); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return new com.codename1.ui.events.DataChangedListener() { + public void dataChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return new com.codename1.ui.events.SelectionListener() { + public void selectionChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return new com.codename1.printing.PrintResultListener() { + public void onResult(com.codename1.printing.PrintResult arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + return lambda; + } + + private static Object adaptValue(Object value, Class type) { + if (!(value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue)) { + return value; + } + // Direct fit when LambdaValue already implements the target SAM + // (Runnable, Function, Comparator, ...). + if (type.isInstance(value)) { + return value; + } + return adaptLambdaValue((bsh.cn1.CN1LambdaSupport.LambdaValue) value, type); + } + + private static int toIntValue(Object value) { + if (value instanceof Number) return ((Number) value).intValue(); + if (value instanceof Character) return (int) ((Character) value).charValue(); + throw new ClassCastException("Cannot coerce " + + (value == null ? "null" : value.getClass().getName()) + " to int"); + } + + private static boolean matches(Object[] args, Class[] paramTypes, boolean varArgs) { + if (!varArgs) { + if (args.length != paramTypes.length) { + return false; + } + for (int i = 0; i < paramTypes.length; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + return true; + } + if (paramTypes.length == 0) { + return true; + } + int fixedCount = paramTypes.length - 1; + if (args.length < fixedCount) { + return false; + } + for (int i = 0; i < fixedCount; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < args.length; i++) { + if (!matchesType(args[i], componentType)) { + return false; + } + } + return true; + } + + private static boolean matchesType(Object value, Class type) { + if (type == Object.class) { + return true; + } + if (value == null) { + return !type.isPrimitive(); + } + if (type.isArray()) { + return type.isInstance(value); + } + if ("boolean".equals(type.getName()) || type == Boolean.class) { + return value instanceof Boolean; + } + if ("char".equals(type.getName()) || type == Character.class) { + return value instanceof Character; + } + if ("byte".equals(type.getName()) || type == Byte.class || "short".equals(type.getName()) || type == Short.class + || "int".equals(type.getName()) || type == Integer.class || "long".equals(type.getName()) || type == Long.class + || "float".equals(type.getName()) || type == Float.class || "double".equals(type.getName()) || type == Double.class) { + // Java widens char to int implicitly, so accept Character + // for any int-or-larger numeric slot. + return value instanceof Number || value instanceof Character; + } + if (value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue) { + // LambdaValue implements common SAMs directly (Runnable, + // Function, Predicate, Comparator, ...). Also accept any + // CN1 SAM the listener-bridge knows how to wrap. + return type.isInstance(value) || isSamInterface(type); + } + return type.isInstance(value); + } + + private static CN1AccessException unsupportedConstruct(Class type, Object[] args) { + return new CN1AccessException("Generated constructor dispatch not implemented for " + type.getName() + describeArgs(args)); + } + + private static CN1AccessException unsupportedStatic(Class type, String name, Object[] args) { + return new CN1AccessException("Generated static dispatch not implemented for " + type.getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedInstance(Object target, String name, Object[] args) { + return new CN1AccessException("Generated instance dispatch not implemented for " + target.getClass().getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedStaticField(Class type, String name) { + return new CN1AccessException("Generated static field access not implemented for " + type.getName() + "." + name); + } + + private static CN1AccessException unsupportedField(Object target, String name) { + return new CN1AccessException("Generated field access not implemented for " + target.getClass().getName() + "." + name); + } + + private static CN1AccessException unsupportedStaticFieldWrite(Class type, String name, Object value) { + return new CN1AccessException("Generated static field write not implemented for " + type.getName() + "." + name + " value=" + describeValue(value)); + } + + private static CN1AccessException unsupportedFieldWrite(Object target, String name, Object value) { + return new CN1AccessException("Generated field write not implemented for " + target.getClass().getName() + "." + name + " value=" + describeValue(value)); + } + + private static String describeArgs(Object[] args) { + if (args == null || args.length == 0) { + return "()"; + } + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < args.length; i++) { + if (i > 0) { + sb.append(", "); + } + sb.append(describeValue(args[i])); + } + sb.append(')'); + return sb.toString(); + } + + private static String describeValue(Object value) { + return value == null ? "null" : value.getClass().getName(); + } +} diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security.java index db3d7b1425c..97249086235 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security.java @@ -121,6 +121,9 @@ private static Class findClassChunk0(String simpleName) { if ("Signature".equals(simpleName)) { return com.codename1.security.Signature.class; } + if ("TapjackingPolicy".equals(simpleName)) { + return com.codename1.security.TapjackingPolicy.class; + } return null; } public static Object construct(Class type, Object[] args) throws Exception { @@ -244,6 +247,12 @@ private static Object invokeStatic2(String name, Object[] safeArgs) throws Excep } private static Object invokeStatic3(String name, Object[] safeArgs) throws Exception { + if ("addTapjackingListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + com.codename1.security.DeviceIntegrity.addTapjackingListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } if ("confirmAttestation".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); @@ -260,6 +269,11 @@ private static Object invokeStatic3(String name, Object[] safeArgs) throws Excep return com.codename1.security.DeviceIntegrity.getEnabledAccessibilityServices(); } } + if ("getTapjackingPolicy".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.security.DeviceIntegrity.getTapjackingPolicy(); + } + } if ("hasUntrustedAccessibilityService".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String[].class}, true)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String[].class}, true); @@ -280,6 +294,22 @@ private static Object invokeStatic3(String name, Object[] safeArgs) throws Excep return com.codename1.security.DeviceIntegrity.isDeviceCompromised(); } } + if ("isHideOverlayWindowsSupported".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.security.DeviceIntegrity.isHideOverlayWindowsSupported(); + } + } + if ("isScreenObscured".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.security.DeviceIntegrity.isScreenObscured(); + } + } + if ("removeTapjackingListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + com.codename1.security.DeviceIntegrity.removeTapjackingListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } if ("requestIntegrityToken".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); @@ -291,12 +321,24 @@ private static Object invokeStatic3(String name, Object[] safeArgs) throws Excep com.codename1.security.DeviceIntegrity.resetAttestation(); return null; } } + if ("setHideOverlayWindows".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + com.codename1.security.DeviceIntegrity.setHideOverlayWindows(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } if ("setSecureScreen".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); com.codename1.security.DeviceIntegrity.setSecureScreen(((Boolean) adaptedArgs[0]).booleanValue()); return null; } } + if ("setTapjackingProtection".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.security.TapjackingPolicy.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.security.TapjackingPolicy.class}, false); + com.codename1.security.DeviceIntegrity.setTapjackingProtection((com.codename1.security.TapjackingPolicy) adaptedArgs[0]); return null; + } + } throw unsupportedStatic(com.codename1.security.DeviceIntegrity.class, name, safeArgs); } @@ -722,6 +764,13 @@ public static Object invoke(Object target, String name, Object[] args) throws Ex unsupported = ex; } } + if (target instanceof com.codename1.security.TapjackingPolicy) { + try { + return invoke12((com.codename1.security.TapjackingPolicy) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } if (unsupported != null) { throw unsupported; } @@ -1100,6 +1149,12 @@ private static Object invoke10(com.codename1.security.KeyPair typedTarget, Strin } private static Object invoke11(com.codename1.security.SecureStorage typedTarget, String name, Object[] safeArgs) throws Exception { + if ("entryState".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.entryState((java.lang.String) adaptedArgs[0]); + } + } if ("get".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); @@ -1130,6 +1185,12 @@ private static Object invoke11(com.codename1.security.SecureStorage typedTarget, return typedTarget.set((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1], (java.lang.String) adaptedArgs[2]); } } + if ("setIfAbsent".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false); + return typedTarget.setIfAbsent((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); + } + } if ("setKeychainAccessGroup".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); @@ -1139,6 +1200,21 @@ private static Object invoke11(com.codename1.security.SecureStorage typedTarget, throw unsupportedInstance(typedTarget, name, safeArgs); } + private static Object invoke12(com.codename1.security.TapjackingPolicy typedTarget, String name, Object[] safeArgs) throws Exception { + if ("blocks".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class, java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class, java.lang.Boolean.class}, false); + return typedTarget.blocks(((Boolean) adaptedArgs[0]).booleanValue(), ((Boolean) adaptedArgs[1]).booleanValue()); + } + } + if ("isDetecting".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isDetecting(); + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + public static Object getStaticField(Class type, String name) throws Exception { if (type == com.codename1.security.BiometricError.class) return getStaticField0(name); if (type == com.codename1.security.BiometricType.class) return getStaticField1(name); @@ -1146,7 +1222,9 @@ public static Object getStaticField(Class type, String name) throws Exception if (type == com.codename1.security.Hash.class) return getStaticField3(name); if (type == com.codename1.security.Jwt.class) return getStaticField4(name); if (type == com.codename1.security.PublicKey.class) return getStaticField5(name); - if (type == com.codename1.security.Signature.class) return getStaticField6(name); + if (type == com.codename1.security.SecureStorage.class) return getStaticField6(name); + if (type == com.codename1.security.Signature.class) return getStaticField7(name); + if (type == com.codename1.security.TapjackingPolicy.class) return getStaticField8(name); throw unsupportedStaticField(type, name); } @@ -1214,6 +1292,13 @@ private static Object getStaticField5(String name) throws Exception { } private static Object getStaticField6(String name) throws Exception { + if ("ENTRY_ABSENT".equals(name)) return com.codename1.security.SecureStorage.ENTRY_ABSENT; + if ("ENTRY_PRESENT".equals(name)) return com.codename1.security.SecureStorage.ENTRY_PRESENT; + if ("ENTRY_UNKNOWN".equals(name)) return com.codename1.security.SecureStorage.ENTRY_UNKNOWN; + throw unsupportedStaticField(com.codename1.security.SecureStorage.class, name); + } + + private static Object getStaticField7(String name) throws Exception { if ("SHA256_WITH_ECDSA".equals(name)) return com.codename1.security.Signature.SHA256_WITH_ECDSA; if ("SHA256_WITH_RSA".equals(name)) return com.codename1.security.Signature.SHA256_WITH_RSA; if ("SHA384_WITH_ECDSA".equals(name)) return com.codename1.security.Signature.SHA384_WITH_ECDSA; @@ -1223,6 +1308,14 @@ private static Object getStaticField6(String name) throws Exception { throw unsupportedStaticField(com.codename1.security.Signature.class, name); } + private static Object getStaticField8(String name) throws Exception { + if ("BLOCK".equals(name)) return com.codename1.security.TapjackingPolicy.BLOCK; + if ("OFF".equals(name)) return com.codename1.security.TapjackingPolicy.OFF; + if ("REPORT".equals(name)) return com.codename1.security.TapjackingPolicy.REPORT; + if ("STRICT".equals(name)) return com.codename1.security.TapjackingPolicy.STRICT; + throw unsupportedStaticField(com.codename1.security.TapjackingPolicy.class, name); + } + public static Object getField(Object target, String name) throws Exception { throw unsupportedField(target, name); } diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security_hardening.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security_hardening.java new file mode 100644 index 00000000000..b5c220de968 --- /dev/null +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security_hardening.java @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ + +package bsh.cn1.gen; + +import bsh.cn1.CN1AccessException; + +public final class GeneratedAccess_com_codename1_security_hardening { + private GeneratedAccess_com_codename1_security_hardening() { + } + + public static Class findClass(String name) { + if (name == null) { + return null; + } + int dot = name.lastIndexOf('.'); + int dollar = name.lastIndexOf('$'); + int sep = dot > dollar ? dot : dollar; + if (sep < 0 || sep == name.length() - 1) { + return null; + } + return findClassBySimpleName(name.substring(sep + 1)); + } + + public static Class findClassBySimpleName(String simpleName) { + Class found0 = findClassChunk0(simpleName); + if (found0 != null) { + return found0; + } + return null; + } + + + private static Class findClassChunk0(String simpleName) { + if ("Hardening".equals(simpleName)) { + return com.codename1.security.hardening.Hardening.class; + } + return null; + } + public static Object construct(Class type, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + throw unsupportedConstruct(type, safeArgs); + } + + public static Object invokeStatic(Class type, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + if (type == com.codename1.security.hardening.Hardening.class) return invokeStatic0(name, safeArgs); + throw unsupportedStatic(type, name, safeArgs); + } + + private static Object invokeStatic0(String name, Object[] safeArgs) throws Exception { + if ("getLevel".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.security.hardening.Hardening.getLevel(); + } + } + if ("getMappingId".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.security.hardening.Hardening.getMappingId(); + } + } + if ("isHardened".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.security.hardening.Hardening.isHardened(); + } + } + throw unsupportedStatic(com.codename1.security.hardening.Hardening.class, name, safeArgs); + } + + public static Object invoke(Object target, String name, Object[] args) throws Exception { + Object[] safeArgs = safeArgs(args); + CN1AccessException unsupported = null; + if (unsupported != null) { + throw unsupported; + } + throw unsupportedInstance(target, name, safeArgs); + } + + public static Object getStaticField(Class type, String name) throws Exception { + throw unsupportedStaticField(type, name); + } + + public static Object getField(Object target, String name) throws Exception { + throw unsupportedField(target, name); + } + + public static void setStaticField(Class type, String name, Object value) throws Exception { + throw unsupportedStaticFieldWrite(type, name, value); + } + + public static void setField(Object target, String name, Object value) throws Exception { + throw unsupportedFieldWrite(target, name, value); + } + + private static Object[] safeArgs(Object[] args) { + return args == null ? new Object[0] : args; + } + + private static Object[] adaptArgs(Object[] args, Class[] paramTypes, boolean varArgs) { + if (args == null || args.length == 0) { + return args == null ? new Object[0] : args; + } + Object[] adapted = args.clone(); + if (!varArgs) { + for (int i = 0; i < Math.min(adapted.length, paramTypes.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + return adapted; + } + if (paramTypes.length == 0) { + return adapted; + } + int fixedCount = paramTypes.length - 1; + for (int i = 0; i < Math.min(fixedCount, adapted.length); i++) { + adapted[i] = adaptValue(adapted[i], paramTypes[i]); + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < adapted.length; i++) { + adapted[i] = adaptValue(adapted[i], componentType); + } + return adapted; + } + + private static boolean isSamInterface(Class type) { + if (type == com.codename1.util.OnComplete.class) { + return true; + } + if (type == com.codename1.util.SuccessCallback.class) { + return true; + } + if (type == com.codename1.util.FailureCallback.class) { + return true; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return true; + } + if (type == java.lang.Runnable.class) { + return true; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return true; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return true; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return true; + } + return false; + } + + private static Object adaptLambdaValue(final bsh.cn1.CN1LambdaSupport.LambdaValue lambda, Class type) { + if (type == com.codename1.util.OnComplete.class) { + return new com.codename1.util.OnComplete() { + public void completed(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.SuccessCallback.class) { + return new com.codename1.util.SuccessCallback() { + public void onSucess(java.lang.Object arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.util.FailureCallback.class) { + return new com.codename1.util.FailureCallback() { + public void onError(java.lang.Object arg0, java.lang.Throwable arg1, int arg2, java.lang.String arg3) { + try { + lambda.invoke(new Object[]{arg0, arg1, arg2, arg3}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.ActionListener.class) { + return new com.codename1.ui.events.ActionListener() { + public void actionPerformed(com.codename1.ui.events.ActionEvent arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == java.lang.Runnable.class) { + return new java.lang.Runnable() { + public void run() { + try { + lambda.invoke(new Object[0]); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.DataChangedListener.class) { + return new com.codename1.ui.events.DataChangedListener() { + public void dataChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.ui.events.SelectionListener.class) { + return new com.codename1.ui.events.SelectionListener() { + public void selectionChanged(int arg0, int arg1) { + try { + lambda.invoke(new Object[]{arg0, arg1}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + if (type == com.codename1.printing.PrintResultListener.class) { + return new com.codename1.printing.PrintResultListener() { + public void onResult(com.codename1.printing.PrintResult arg0) { + try { + lambda.invoke(new Object[]{arg0}); + } catch (bsh.EvalError ex) { + throw new RuntimeException(ex); + } + } + }; + } + return lambda; + } + + private static Object adaptValue(Object value, Class type) { + if (!(value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue)) { + return value; + } + // Direct fit when LambdaValue already implements the target SAM + // (Runnable, Function, Comparator, ...). + if (type.isInstance(value)) { + return value; + } + return adaptLambdaValue((bsh.cn1.CN1LambdaSupport.LambdaValue) value, type); + } + + private static int toIntValue(Object value) { + if (value instanceof Number) return ((Number) value).intValue(); + if (value instanceof Character) return (int) ((Character) value).charValue(); + throw new ClassCastException("Cannot coerce " + + (value == null ? "null" : value.getClass().getName()) + " to int"); + } + + private static boolean matches(Object[] args, Class[] paramTypes, boolean varArgs) { + if (!varArgs) { + if (args.length != paramTypes.length) { + return false; + } + for (int i = 0; i < paramTypes.length; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + return true; + } + if (paramTypes.length == 0) { + return true; + } + int fixedCount = paramTypes.length - 1; + if (args.length < fixedCount) { + return false; + } + for (int i = 0; i < fixedCount; i++) { + if (!matchesType(args[i], paramTypes[i])) { + return false; + } + } + Class componentType = paramTypes[paramTypes.length - 1].getComponentType(); + for (int i = fixedCount; i < args.length; i++) { + if (!matchesType(args[i], componentType)) { + return false; + } + } + return true; + } + + private static boolean matchesType(Object value, Class type) { + if (type == Object.class) { + return true; + } + if (value == null) { + return !type.isPrimitive(); + } + if (type.isArray()) { + return type.isInstance(value); + } + if ("boolean".equals(type.getName()) || type == Boolean.class) { + return value instanceof Boolean; + } + if ("char".equals(type.getName()) || type == Character.class) { + return value instanceof Character; + } + if ("byte".equals(type.getName()) || type == Byte.class || "short".equals(type.getName()) || type == Short.class + || "int".equals(type.getName()) || type == Integer.class || "long".equals(type.getName()) || type == Long.class + || "float".equals(type.getName()) || type == Float.class || "double".equals(type.getName()) || type == Double.class) { + // Java widens char to int implicitly, so accept Character + // for any int-or-larger numeric slot. + return value instanceof Number || value instanceof Character; + } + if (value instanceof bsh.cn1.CN1LambdaSupport.LambdaValue) { + // LambdaValue implements common SAMs directly (Runnable, + // Function, Predicate, Comparator, ...). Also accept any + // CN1 SAM the listener-bridge knows how to wrap. + return type.isInstance(value) || isSamInterface(type); + } + return type.isInstance(value); + } + + private static CN1AccessException unsupportedConstruct(Class type, Object[] args) { + return new CN1AccessException("Generated constructor dispatch not implemented for " + type.getName() + describeArgs(args)); + } + + private static CN1AccessException unsupportedStatic(Class type, String name, Object[] args) { + return new CN1AccessException("Generated static dispatch not implemented for " + type.getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedInstance(Object target, String name, Object[] args) { + return new CN1AccessException("Generated instance dispatch not implemented for " + target.getClass().getName() + "." + name + describeArgs(args)); + } + + private static CN1AccessException unsupportedStaticField(Class type, String name) { + return new CN1AccessException("Generated static field access not implemented for " + type.getName() + "." + name); + } + + private static CN1AccessException unsupportedField(Object target, String name) { + return new CN1AccessException("Generated field access not implemented for " + target.getClass().getName() + "." + name); + } + + private static CN1AccessException unsupportedStaticFieldWrite(Class type, String name, Object value) { + return new CN1AccessException("Generated static field write not implemented for " + type.getName() + "." + name + " value=" + describeValue(value)); + } + + private static CN1AccessException unsupportedFieldWrite(Object target, String name, Object value) { + return new CN1AccessException("Generated field write not implemented for " + target.getClass().getName() + "." + name + " value=" + describeValue(value)); + } + + private static String describeArgs(Object[] args) { + if (args == null || args.length == 0) { + return "()"; + } + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < args.length; i++) { + if (i > 0) { + sb.append(", "); + } + sb.append(describeValue(args[i])); + } + sb.append(')'); + return sb.toString(); + } + + private static String describeValue(Object value) { + return value == null ? "null" : value.getClass().getName(); + } +} diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security_shield.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security_shield.java index b6dcf961c6d..744c2b3b7e0 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security_shield.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_security_shield.java @@ -756,6 +756,7 @@ private static Object getStaticField5(String name) throws Exception { if ("JAILBREAK".equals(name)) return com.codename1.security.shield.ShieldSignal.JAILBREAK; if ("REPACKAGED".equals(name)) return com.codename1.security.shield.ShieldSignal.REPACKAGED; if ("ROOT".equals(name)) return com.codename1.security.shield.ShieldSignal.ROOT; + if ("TAPJACK".equals(name)) return com.codename1.security.shield.ShieldSignal.TAPJACK; throw unsupportedStaticField(com.codename1.security.shield.ShieldSignal.class, name); } diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_surfaces.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_surfaces.java index 44fa1d8ba18..6f0261e1232 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_surfaces.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_surfaces.java @@ -323,6 +323,12 @@ private static Object invokeStatic3(String name, Object[] safeArgs) throws Excep return com.codename1.surfaces.SurfaceSerializer.serializeLiveActivity((com.codename1.surfaces.LiveActivityDescriptor) adaptedArgs[0], (java.util.Map) adaptedArgs[1], (java.util.Map) adaptedArgs[2]); } } + if ("serializeNodeToMap".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.surfaces.SurfaceNode.class, java.util.Map.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.surfaces.SurfaceNode.class, java.util.Map.class}, false); + return com.codename1.surfaces.SurfaceSerializer.serializeNodeToMap((com.codename1.surfaces.SurfaceNode) adaptedArgs[0], (java.util.Map) adaptedArgs[1]); + } + } if ("serializeState".equals(name)) { if (matches(safeArgs, new Class[]{java.util.Map.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.util.Map.class}, false); diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ui.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ui.java index fedfd2b97e8..4dab6087e1c 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ui.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ui.java @@ -13139,6 +13139,12 @@ private static Object invoke4(com.codename1.ui.CodeEditor typedTarget, String na typedTarget.addPointerReleasedListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } + if ("addProtectedEditListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addProtectedEditListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } if ("addPullToRefresh".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Runnable.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Runnable.class}, false); @@ -14437,6 +14443,12 @@ private static Object invoke4(com.codename1.ui.CodeEditor typedTarget, String na typedTarget.removePointerReleasedListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } + if ("removeProtectedEditListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removeProtectedEditListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } if ("removeReadyListener".equals(name)) { if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); @@ -14591,6 +14603,12 @@ private static Object invoke4(com.codename1.ui.CodeEditor typedTarget, String na typedTarget.setCursor(toIntValue(adaptedArgs[0])); return null; } } + if ("setCursorPosition".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + typedTarget.setCursorPosition(toIntValue(adaptedArgs[0])); return null; + } + } if ("setDiagnostics".equals(name)) { if (matches(safeArgs, new Class[]{java.util.List.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.util.List.class}, false); @@ -14871,6 +14889,12 @@ private static Object invoke4(com.codename1.ui.CodeEditor typedTarget, String na return typedTarget.setPropertyValue((java.lang.String) adaptedArgs[0], (java.lang.Object) adaptedArgs[1]); } } + if ("setProtectedRegionMarkers".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false); + typedTarget.setProtectedRegionMarkers((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); return null; + } + } if ("setPullToRefresh".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Runnable.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Runnable.class}, false); @@ -73790,6 +73814,12 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name typedTarget.addPostureListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } + if ("addTapjackingListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.addTapjackingListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } if ("addVirtualKeyboardListener".equals(name)) { if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); @@ -74030,6 +74060,24 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name return typedTarget.createThread((java.lang.Runnable) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); } } + if ("databaseIdentityForEngineFile".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.databaseIdentityForEngineFile((java.lang.String) adaptedArgs[0]); + } + } + if ("databaseManagedKeyIdentity".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.databaseManagedKeyIdentity((java.lang.String) adaptedArgs[0]); + } + } + if ("databaseRegistryIdentity".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.databaseRegistryIdentity((java.lang.String) adaptedArgs[0]); + } + } if ("delete".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); @@ -74336,6 +74384,11 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name return typedTarget.getHealth(); } } + if ("getHomeBridge".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getHomeBridge(); + } + } if ("getImageIO".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getImageIO(); @@ -74355,6 +74408,11 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name return typedTarget.getInitialWindowSizeHintPercent(); } } + if ("getIntentBridge".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getIntentBridge(); + } + } if ("getInvisibleAreaUnderVKB".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getInvisibleAreaUnderVKB(); @@ -74545,6 +74603,11 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name return typedTarget.getSurfaceBridge(); } } + if ("getTapjackingPolicy".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.getTapjackingPolicy(); + } + } if ("getUdid".equals(name)) { if (safeArgs.length == 0) { return typedTarget.getUdid(); @@ -74709,6 +74772,11 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name return typedTarget.isBidiAlgorithm(); } } + if ("isBlobQueryParameterSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isBlobQueryParameterSupported(); + } + } if ("isBoldTextEnabled".equals(name)) { if (safeArgs.length == 0) { return typedTarget.isBoldTextEnabled(); @@ -74760,6 +74828,22 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name return typedTarget.isDatabaseCustomPathSupported(); } } + if ("isDatabaseEncryptionSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isDatabaseEncryptionSupported(); + } + } + if ("isDatabaseFileEncrypted".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.isDatabaseFileEncrypted((java.lang.String) adaptedArgs[0]); + } + } + if ("isDatabaseManagedKeyHardwareBacked".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isDatabaseManagedKeyHardwareBacked(); + } + } if ("isDebuggableBuild".equals(name)) { if (safeArgs.length == 0) { return typedTarget.isDebuggableBuild(); @@ -74841,6 +74925,11 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name return typedTarget.isGrayscaleEnabled(); } } + if ("isHideOverlayWindowsSupported".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isHideOverlayWindowsSupported(); + } + } if ("isHighContrastEnabled".equals(name)) { if (safeArgs.length == 0) { return typedTarget.isHighContrastEnabled(); @@ -74988,11 +75077,21 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name return typedTarget.isReduceTransparencyEnabled(); } } + if ("isRelativeAttachmentNameResolvable".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isRelativeAttachmentNameResolvable(); + } + } if ("isRightMouseButtonDown".equals(name)) { if (safeArgs.length == 0) { return typedTarget.isRightMouseButtonDown(); } } + if ("isScreenObscured".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isScreenObscured(); + } + } if ("isScreenReaderEnabled".equals(name)) { if (safeArgs.length == 0) { return typedTarget.isScreenReaderEnabled(); @@ -75133,6 +75232,12 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name typedTarget.onEditingComplete((com.codename1.ui.Component) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); return null; } } + if ("openDatabaseConnections".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.openDatabaseConnections((java.lang.String) adaptedArgs[0]); + } + } if ("openFileChooser".equals(name)) { if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class, java.lang.String.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class, java.lang.String.class}, false); @@ -75166,6 +75271,16 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); return typedTarget.openOrCreate((java.lang.String) adaptedArgs[0]); } + if (matches(safeArgs, new Class[]{java.lang.String.class, com.codename1.db.DatabaseConfig.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, com.codename1.db.DatabaseConfig.class}, false); + return typedTarget.openOrCreate((java.lang.String) adaptedArgs[0], (com.codename1.db.DatabaseConfig) adaptedArgs[1]); + } + } + if ("openOrCreateForRekey".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.openOrCreateForRekey((java.lang.String) adaptedArgs[0]); + } } if ("platformUsesInputMode".equals(name)) { if (safeArgs.length == 0) { @@ -75289,6 +75404,12 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name typedTarget.removePostureListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; } } + if ("removeTapjackingListener".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); + typedTarget.removeTapjackingListener((com.codename1.ui.events.ActionListener) adaptedArgs[0]); return null; + } + } if ("removeVirtualKeyboardListener".equals(name)) { if (matches(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.events.ActionListener.class}, false); @@ -75461,6 +75582,12 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name typedTarget.setFramerate(toIntValue(adaptedArgs[0])); return null; } } + if ("setHideOverlayWindows".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); + typedTarget.setHideOverlayWindows(((Boolean) adaptedArgs[0]).booleanValue()); return null; + } + } if ("setInitialWindowSizeHintPercent".equals(name)) { if (matches(safeArgs, new Class[]{com.codename1.ui.geom.Dimension.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.ui.geom.Dimension.class}, false); @@ -75551,6 +75678,12 @@ private static Object invoke37(com.codename1.ui.Display typedTarget, String name typedTarget.setShowVirtualKeyboard(((Boolean) adaptedArgs[0]).booleanValue()); return null; } } + if ("setTapjackingProtection".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.security.TapjackingPolicy.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.security.TapjackingPolicy.class}, false); + typedTarget.setTapjackingProtection((com.codename1.security.TapjackingPolicy) adaptedArgs[0]); return null; + } + } if ("setThirdSoftButton".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Boolean.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Boolean.class}, false); @@ -90559,12 +90692,27 @@ private static Object invoke66(com.codename1.ui.EditField typedTarget, String na return typedTarget.containsOrOwns(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); } } + if ("copySelection".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.copySelection(); return null; + } + } if ("createStyleAnimation".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Integer.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Integer.class}, false); return typedTarget.createStyleAnimation((java.lang.String) adaptedArgs[0], toIntValue(adaptedArgs[1])); } } + if ("cutSelection".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.cutSelection(); return null; + } + } + if ("deleteBackward".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.deleteBackward(); return null; + } + } if ("deleteSurroundingText".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); @@ -91452,6 +91600,11 @@ private static Object invoke66(com.codename1.ui.EditField typedTarget, String na typedTarget.paintShadows((com.codename1.ui.Graphics) adaptedArgs[0], toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2])); return null; } } + if ("pasteClipboard".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.pasteClipboard(); return null; + } + } if ("performRedo".equals(name)) { if (safeArgs.length == 0) { typedTarget.performRedo(); return null; diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ui_editor.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ui_editor.java index d7e7785051d..888fec5b64d 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ui_editor.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_ui_editor.java @@ -675,12 +675,27 @@ private static Object invoke1(com.codename1.ui.editor.CodeView typedTarget, Stri return typedTarget.containsOrOwns(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); } } + if ("copySelection".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.copySelection(); return null; + } + } if ("createStyleAnimation".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Integer.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Integer.class}, false); return typedTarget.createStyleAnimation((java.lang.String) adaptedArgs[0], toIntValue(adaptedArgs[1])); } } + if ("cutSelection".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.cutSelection(); return null; + } + } + if ("deleteBackward".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.deleteBackward(); return null; + } + } if ("deleteSurroundingText".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); @@ -1532,6 +1547,11 @@ private static Object invoke1(com.codename1.ui.editor.CodeView typedTarget, Stri typedTarget.paintShadows((com.codename1.ui.Graphics) adaptedArgs[0], toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2])); return null; } } + if ("pasteClipboard".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.pasteClipboard(); return null; + } + } if ("performRedo".equals(name)) { if (safeArgs.length == 0) { typedTarget.performRedo(); return null; @@ -2082,6 +2102,12 @@ private static Object invoke1(com.codename1.ui.editor.CodeView typedTarget, Stri return typedTarget.setPropertyValue((java.lang.String) adaptedArgs[0], (java.lang.Object) adaptedArgs[1]); } } + if ("setProtectedRegionMarkers".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class}, false); + typedTarget.setProtectedRegionMarkers((java.lang.String) adaptedArgs[0], (java.lang.String) adaptedArgs[1]); return null; + } + } if ("setPullToRefresh".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Runnable.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Runnable.class}, false); @@ -2508,12 +2534,27 @@ private static Object invoke3(com.codename1.ui.editor.RichView typedTarget, Stri return typedTarget.containsOrOwns(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); } } + if ("copySelection".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.copySelection(); return null; + } + } if ("createStyleAnimation".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Integer.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Integer.class}, false); return typedTarget.createStyleAnimation((java.lang.String) adaptedArgs[0], toIntValue(adaptedArgs[1])); } } + if ("cutSelection".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.cutSelection(); return null; + } + } + if ("deleteBackward".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.deleteBackward(); return null; + } + } if ("deleteSurroundingText".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); @@ -3408,6 +3449,11 @@ private static Object invoke3(com.codename1.ui.editor.RichView typedTarget, Stri typedTarget.paintShadows((com.codename1.ui.Graphics) adaptedArgs[0], toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2])); return null; } } + if ("pasteClipboard".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.pasteClipboard(); return null; + } + } if ("performRedo".equals(name)) { if (safeArgs.length == 0) { typedTarget.performRedo(); return null; @@ -4478,12 +4524,27 @@ private static Object invoke5(com.codename1.ui.editor.EditorView typedTarget, St return typedTarget.containsOrOwns(toIntValue(adaptedArgs[0]), toIntValue(adaptedArgs[1])); } } + if ("copySelection".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.copySelection(); return null; + } + } if ("createStyleAnimation".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Integer.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Integer.class}, false); return typedTarget.createStyleAnimation((java.lang.String) adaptedArgs[0], toIntValue(adaptedArgs[1])); } } + if ("cutSelection".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.cutSelection(); return null; + } + } + if ("deleteBackward".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.deleteBackward(); return null; + } + } if ("deleteSurroundingText".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class, java.lang.Integer.class}, false); @@ -5330,6 +5391,11 @@ private static Object invoke5(com.codename1.ui.editor.EditorView typedTarget, St typedTarget.paintShadows((com.codename1.ui.Graphics) adaptedArgs[0], toIntValue(adaptedArgs[1]), toIntValue(adaptedArgs[2])); return null; } } + if ("pasteClipboard".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.pasteClipboard(); return null; + } + } if ("performRedo".equals(name)) { if (safeArgs.length == 0) { typedTarget.performRedo(); return null; diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_util.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_util.java index acf718001d3..db52a07e0d8 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_util.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_util.java @@ -1528,6 +1528,16 @@ private static Object invoke9(com.codename1.util.EasyThread typedTarget, String typedTarget.addErrorListener((com.codename1.util.EasyThread.ErrorListener) adaptedArgs[0]); return null; } } + if ("awaitFinished".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.awaitFinished(); return null; + } + } + if ("isFinished".equals(name)) { + if (safeArgs.length == 0) { + return typedTarget.isFinished(); + } + } if ("isThisIt".equals(name)) { if (safeArgs.length == 0) { return typedTarget.isThisIt(); @@ -1538,6 +1548,11 @@ private static Object invoke9(com.codename1.util.EasyThread typedTarget, String typedTarget.kill(); return null; } } + if ("killWhenIdle".equals(name)) { + if (safeArgs.length == 0) { + typedTarget.killWhenIdle(); return null; + } + } if ("removeErrorListener".equals(name)) { if (matches(safeArgs, new Class[]{com.codename1.util.EasyThread.ErrorListener.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.util.EasyThread.ErrorListener.class}, false); diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_wearable.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_wearable.java index 4de75de0b11..15a09249c0c 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_wearable.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_com_codename1_wearable.java @@ -55,6 +55,9 @@ private static Class findClassChunk0(String simpleName) { if ("WearableConnection".equals(simpleName)) { return com.codename1.wearable.WearableConnection.class; } + if ("DroppedDeliveryHandler".equals(simpleName)) { + return com.codename1.wearable.WearableConnection.DroppedDeliveryHandler.class; + } if ("WearableDataListener".equals(simpleName)) { return com.codename1.wearable.WearableDataListener.class; } @@ -133,18 +136,38 @@ private static Object invokeStatic0(String name, Object[] safeArgs) throws Excep Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, byte[].class, java.lang.Runnable.class}, false); return com.codename1.wearable.WearableConnection.deliverDataChangedTracked((java.lang.String) adaptedArgs[0], (byte[]) adaptedArgs[1], (java.lang.Runnable) adaptedArgs[2]); } + if (matches(safeArgs, new Class[]{java.lang.String.class, byte[].class, java.lang.Runnable.class, java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, byte[].class, java.lang.Runnable.class, java.lang.Runnable.class}, false); + return com.codename1.wearable.WearableConnection.deliverDataChangedTracked((java.lang.String) adaptedArgs[0], (byte[]) adaptedArgs[1], (java.lang.Runnable) adaptedArgs[2], (java.lang.Runnable) adaptedArgs[3]); + } } if ("deliverDataRemoved".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); com.codename1.wearable.WearableConnection.deliverDataRemoved((java.lang.String) adaptedArgs[0]); return null; } + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Runnable.class}, false); + com.codename1.wearable.WearableConnection.deliverDataRemoved((java.lang.String) adaptedArgs[0], (java.lang.Runnable) adaptedArgs[1]); return null; + } + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Runnable.class, java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Runnable.class, java.lang.Runnable.class}, false); + com.codename1.wearable.WearableConnection.deliverDataRemoved((java.lang.String) adaptedArgs[0], (java.lang.Runnable) adaptedArgs[1], (java.lang.Runnable) adaptedArgs[2]); return null; + } } if ("deliverMessage".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class, byte[].class, java.lang.Integer.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, byte[].class, java.lang.Integer.class}, false); com.codename1.wearable.WearableConnection.deliverMessage((java.lang.String) adaptedArgs[0], (byte[]) adaptedArgs[1], toIntValue(adaptedArgs[2])); return null; } + if (matches(safeArgs, new Class[]{java.lang.String.class, byte[].class, java.lang.Integer.class, java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, byte[].class, java.lang.Integer.class, java.lang.Runnable.class}, false); + com.codename1.wearable.WearableConnection.deliverMessage((java.lang.String) adaptedArgs[0], (byte[]) adaptedArgs[1], toIntValue(adaptedArgs[2]), (java.lang.Runnable) adaptedArgs[3]); return null; + } + if (matches(safeArgs, new Class[]{java.lang.String.class, byte[].class, java.lang.Integer.class, java.lang.Runnable.class, java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, byte[].class, java.lang.Integer.class, java.lang.Runnable.class, java.lang.Runnable.class}, false); + com.codename1.wearable.WearableConnection.deliverMessage((java.lang.String) adaptedArgs[0], (byte[]) adaptedArgs[1], toIntValue(adaptedArgs[2]), (java.lang.Runnable) adaptedArgs[3], (java.lang.Runnable) adaptedArgs[4]); return null; + } } if ("deliverReply".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Integer.class, byte[].class, java.lang.String.class}, false)) { @@ -168,6 +191,22 @@ private static Object invokeStatic0(String name, Object[] safeArgs) throws Excep return com.codename1.wearable.WearableConnection.getDataPaths(); } } + if ("hasDataListener".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.wearable.WearableConnection.hasDataListener(); + } + } + if ("hasMessageListener".equals(name)) { + if (safeArgs.length == 0) { + return com.codename1.wearable.WearableConnection.hasMessageListener(); + } + } + if ("hasPendingReply".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.Integer.class}, false); + return com.codename1.wearable.WearableConnection.hasPendingReply(toIntValue(adaptedArgs[0])); + } + } if ("isCompanionAppInstalled".equals(name)) { if (safeArgs.length == 0) { return com.codename1.wearable.WearableConnection.isCompanionAppInstalled(); @@ -223,6 +262,23 @@ private static Object invokeStatic0(String name, Object[] safeArgs) throws Excep com.codename1.wearable.WearableConnection.removeStateListener((com.codename1.wearable.WearableStateListener) adaptedArgs[0]); return null; } } + if ("requestReplayAfterDrain".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Runnable.class}, false); + com.codename1.wearable.WearableConnection.requestReplayAfterDrain((java.lang.String) adaptedArgs[0], (java.lang.Runnable) adaptedArgs[1]); return null; + } + } + if ("resetForReload".equals(name)) { + if (safeArgs.length == 0) { + com.codename1.wearable.WearableConnection.resetForReload(); return null; + } + } + if ("runWhenListenerRegisters".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.Runnable.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.Runnable.class}, false); + com.codename1.wearable.WearableConnection.runWhenListenerRegisters((java.lang.String) adaptedArgs[0], (java.lang.Runnable) adaptedArgs[1]); return null; + } + } if ("sendMessage".equals(name)) { if (matches(safeArgs, new Class[]{com.codename1.wearable.WearableMessage.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.wearable.WearableMessage.class}, false); @@ -233,6 +289,12 @@ private static Object invokeStatic0(String name, Object[] safeArgs) throws Excep com.codename1.wearable.WearableConnection.sendMessage((com.codename1.wearable.WearableMessage) adaptedArgs[0], (com.codename1.wearable.WearableReplyHandler) adaptedArgs[1]); return null; } } + if ("setDroppedDeliveryHandler".equals(name)) { + if (matches(safeArgs, new Class[]{com.codename1.wearable.WearableConnection.DroppedDeliveryHandler.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.wearable.WearableConnection.DroppedDeliveryHandler.class}, false); + com.codename1.wearable.WearableConnection.setDroppedDeliveryHandler((com.codename1.wearable.WearableConnection.DroppedDeliveryHandler) adaptedArgs[0]); return null; + } + } if ("transferFile".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, byte[].class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class, java.lang.String.class, byte[].class}, false); @@ -269,30 +331,37 @@ public static Object invoke(Object target, String name, Object[] args) throws Ex unsupported = ex; } } + if (target instanceof com.codename1.wearable.WearableConnection.DroppedDeliveryHandler) { + try { + return invoke2((com.codename1.wearable.WearableConnection.DroppedDeliveryHandler) target, name, safeArgs); + } catch (CN1AccessException ex) { + unsupported = ex; + } + } if (target instanceof com.codename1.wearable.WearableDataListener) { try { - return invoke2((com.codename1.wearable.WearableDataListener) target, name, safeArgs); + return invoke3((com.codename1.wearable.WearableDataListener) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.wearable.WearableMessageListener) { try { - return invoke3((com.codename1.wearable.WearableMessageListener) target, name, safeArgs); + return invoke4((com.codename1.wearable.WearableMessageListener) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.wearable.WearableReplyHandler) { try { - return invoke4((com.codename1.wearable.WearableReplyHandler) target, name, safeArgs); + return invoke5((com.codename1.wearable.WearableReplyHandler) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } } if (target instanceof com.codename1.wearable.WearableStateListener) { try { - return invoke5((com.codename1.wearable.WearableStateListener) target, name, safeArgs); + return invoke6((com.codename1.wearable.WearableStateListener) target, name, safeArgs); } catch (CN1AccessException ex) { unsupported = ex; } @@ -419,7 +488,17 @@ private static Object invoke1(com.codename1.wearable.WearableNode typedTarget, S throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke2(com.codename1.wearable.WearableDataListener typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke2(com.codename1.wearable.WearableConnection.DroppedDeliveryHandler typedTarget, String name, Object[] safeArgs) throws Exception { + if ("deliveryDropped".equals(name)) { + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + typedTarget.deliveryDropped((java.lang.String) adaptedArgs[0]); return null; + } + } + throw unsupportedInstance(typedTarget, name, safeArgs); + } + + private static Object invoke3(com.codename1.wearable.WearableDataListener typedTarget, String name, Object[] safeArgs) throws Exception { if ("dataChanged".equals(name)) { if (matches(safeArgs, new Class[]{com.codename1.wearable.WearableMessage.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.wearable.WearableMessage.class}, false); @@ -435,7 +514,7 @@ private static Object invoke2(com.codename1.wearable.WearableDataListener typedT throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke3(com.codename1.wearable.WearableMessageListener typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke4(com.codename1.wearable.WearableMessageListener typedTarget, String name, Object[] safeArgs) throws Exception { if ("messageReceived".equals(name)) { if (matches(safeArgs, new Class[]{com.codename1.wearable.WearableMessage.class, java.lang.Boolean.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{com.codename1.wearable.WearableMessage.class, java.lang.Boolean.class}, false); @@ -445,7 +524,7 @@ private static Object invoke3(com.codename1.wearable.WearableMessageListener typ throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke4(com.codename1.wearable.WearableReplyHandler typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke5(com.codename1.wearable.WearableReplyHandler typedTarget, String name, Object[] safeArgs) throws Exception { if ("replyFailed".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); @@ -461,7 +540,7 @@ private static Object invoke4(com.codename1.wearable.WearableReplyHandler typedT throw unsupportedInstance(typedTarget, name, safeArgs); } - private static Object invoke5(com.codename1.wearable.WearableStateListener typedTarget, String name, Object[] safeArgs) throws Exception { + private static Object invoke6(com.codename1.wearable.WearableStateListener typedTarget, String name, Object[] safeArgs) throws Exception { if ("connectionStateChanged".equals(name)) { if (safeArgs.length == 0) { typedTarget.connectionStateChanged(); return null; diff --git a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_java_io.java b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_java_io.java index 57a729dedf9..6c3406ee5bc 100644 --- a/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_java_io.java +++ b/scripts/cn1playground/common/src/main/java/bsh/cn1/gen/GeneratedAccess_java_io.java @@ -479,6 +479,10 @@ private static Object invoke1(java.io.ByteArrayOutputStream typedTarget, String if (safeArgs.length == 0) { return typedTarget.toString(); } + if (matches(safeArgs, new Class[]{java.lang.String.class}, false)) { + Object[] adaptedArgs = adaptArgs(safeArgs, new Class[]{java.lang.String.class}, false); + return typedTarget.toString((java.lang.String) adaptedArgs[0]); + } } if ("write".equals(name)) { if (matches(safeArgs, new Class[]{java.lang.Integer.class}, false)) { diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java index 9b2c3666391..eafe3a95b44 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java @@ -96,6 +96,9 @@ public enum Section { BASIC, BUILD_HINTS, EXTENSIONS, ADVANCED } private ProjectBinding binding; private SettingsProperties settings; private BuildHintCatalog buildHints = BuildHintCatalog.load(); + /// hint name -> the annotation attribute that declares it, e.g. "@Ios(pods)". + /// Empty when the project has not been built, or declares none. + private java.util.Map annotationOwnedHints = new java.util.HashMap<>(); private Section section = Section.BASIC; private Form form; private Container page; @@ -227,6 +230,7 @@ private void loadProject() { Log.e(ex); } buildHints = BuildHintCatalog.load(); + annotationOwnedHints = loadAnnotationOwnedHints(); } } @@ -655,6 +659,7 @@ private void animatePage() { private Component hintRow(BuildHintMetadata meta) { Container row = new Container(BoxLayout.y()); row.setUIID(uiid("SettingsRow")); + String ownedBy = annotationOwnedHints.get(meta.name()); boolean active = hasBuildHint(meta.name()); String value = active ? settings.getBuildHint(meta.name()) : ""; BuildHintType effectiveType = effectiveHintType(meta, value); @@ -667,8 +672,22 @@ private Component hintRow(BuildHintMetadata meta) { if (active) { metaLine.add(new Label("Active", uiid("SettingsActiveBadge"))); } + if (ownedBy != null) { + metaLine.add(new Label(ownedBy, uiid("SettingsRowMeta"))); + } text.add(name).add(metaLine); - if (active) { + if (ownedBy != null) { + // Set by an annotation on the main class. Editing it here would write a + // second declaration and the next build would refuse the project, so the + // value is shown and the controls are withheld. + TextArea owned = new TextArea("Set by " + ownedBy + " on the main class. " + + "Change it there -- declaring it here as well fails the build."); + owned.setUIID(uiid("SettingsRowText")); + owned.setEditable(false); + owned.setFocusable(false); + text.add(owned); + row.add(text); + } else if (active) { text.add(activeHintEditor(meta, value, effectiveType)); } else { Container controls = new Container(new FlowLayout(Component.LEFT, Component.CENTER)); @@ -686,7 +705,7 @@ private Component hintRow(BuildHintMetadata meta) { header.add(BorderLayout.EAST, controls); row.add(header); } - if (active) { + if (active && ownedBy == null) { row.add(text); } TextArea details = new TextArea(meta.description()); @@ -2049,4 +2068,53 @@ public boolean isScrollableY() { return false; } } + + /// Reads the hints the main class's annotations declare. + /// + /// The annotation processor writes this file into `target/classes` on every + /// build and deletes it when the last annotation goes away, so it is the + /// authoritative statement of what the annotations currently declare -- and + /// it carries `cn1.buildHints.origin.`, which names the attribute. + /// + /// This matters because a hint declared by an annotation must not also be + /// written into `codenameone_settings.properties`: the next build fails with + /// the duplicate-declaration error. Without this the Add button would create + /// exactly that, silently, for any hint the generated project ships as an + /// annotation. + /// + /// An unbuilt project has no file and no annotation-owned hints, which is the + /// same conservative answer this tool gave before. + private java.util.Map loadAnnotationOwnedHints() { + java.util.Map out = new java.util.HashMap<>(); + if (binding == null || binding.projectDir() == null) { + return out; + } + String path = binding.projectDir() + "/target/classes/META-INF/codenameone/build-hints.properties"; + InputStream in = null; + try { + String url = ProjectIO.fsUrl(path); + FileSystemStorage fs = FileSystemStorage.getInstance(); + if (!fs.exists(url)) { + return out; + } + in = fs.openInputStream(url); + String text = Util.readToString(in, "ISO-8859-1"); + String originPrefix = "cn1.buildHints.origin."; + for (String line : com.codename1.util.StringUtil.tokenize(text, "\n")) { + String t = line.trim(); + if (!t.startsWith(originPrefix)) { + continue; + } + int eq = t.indexOf('='); + if (eq > originPrefix.length()) { + out.put(t.substring(originPrefix.length(), eq).trim(), t.substring(eq + 1).trim()); + } + } + } catch (Exception ex) { + Log.e(ex); + } finally { + Util.cleanup(in); + } + return out; + } } diff --git a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java index 38673e3f57e..55741ec3ba8 100644 --- a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java +++ b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java @@ -104,6 +104,27 @@ public void dynamicFamiliesAreNotOffered() { } } + /** + * The generated project ships hints like ios.themeMode as annotations, not + * properties lines. The catalog has to say which hints have an annotation + * form so the Build Hints UI can refuse to write a second declaration -- + * doing so would fail the very next build with a duplicate-hint error. + */ + @Test + public void everyAnnotatedHintNamesItsAttribute() { + BuildHintCatalog catalog = BuildHintCatalog.load(); + int annotated = 0; + for (BuildHintMetadata h : catalog.all()) { + if (h.annotation() == null) { + continue; + } + annotated++; + assertTrue(h.annotation().startsWith("@"), h.name() + " -> " + h.annotation()); + assertTrue(h.annotation().endsWith(")"), h.name() + " -> " + h.annotation()); + } + assertTrue(annotated > 50, "expected the curated set, got " + annotated); + } + @Test public void searchStillMatchesOnNameAndDescription() { BuildHintCatalog catalog = BuildHintCatalog.load(); From 53da7c3402d4eefd94e76df56990e03677666dc7 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 04:43:13 +0300 Subject: [PATCH 08/23] Defer the generated-project templates to a follow-up Every project the archetype and the initializr produce is pinned to a released Codename One version -- the initializr hardcodes 7.0.267 in GeneratorModel.CN1_PLUGIN_VERSION -- and no released core carries com.codename1.annotations.buildhints. So a generated project would import annotations that do not resolve and fail to compile before the user has written a line, and the settings those templates stopped declaring would simply be gone. The templates are reverted to exactly their previous state: the archetype's __mainName__.java and codenameone_settings.properties, and the initializr's common.zip and four source archives. They can move to annotations in a follow-up once a release containing the package is out. The generated build hint table is dropped from the agent skill reference for the same reason -- it documented a form those projects cannot use yet -- so the generator no longer rewrites markdown at all. What stays from that area is unrelated to annotations: the skill reference described build hints that no builder reads, so a reader copying them got a green build and no effect. android.xPermissions is spelled android.xpermissions, android.minSdkVersion is android.min_sdk_version, and android.sdkVersion, android.googlePlayVersion, build.compile, build.timeout, javascript.html5, javascript.bundleResources and ios.orientation do not exist at all. Those corrections are right for the published version too, and the catalog gate now holds our own documentation to them. Co-Authored-By: Claude Opus 5 (1M context) --- .../build/shared/BuildHintCodeGenerator.java | 83 +------- .../common/codenameone_settings.properties | 27 ++- .../common/src/main/java/__mainName__.java | 13 -- scripts/copyright-header-exclusions.txt | 1 - scripts/gen-build-hint-annotations.sh | 4 +- .../src/main/resources/barebones-src.zip | Bin 1435 -> 1327 bytes .../common/src/main/resources/common.zip | Bin 251603 -> 251573 bytes .../common/src/main/resources/grub-src.zip | Bin 275075 -> 279805 bytes .../common/src/main/resources/kotlin-src.zip | Bin 1563 -> 1507 bytes .../common/src/main/resources/skill/SKILL.md | 2 +- .../skill/references/android-to-cn1.md | 2 +- .../skill/references/build-and-run.md | 24 +-- .../resources/skill/references/build-hints.md | 185 ++++-------------- .../skill/references/native-interfaces.md | 31 ++- .../common/src/main/resources/tweet-src.zip | Bin 356080 -> 357703 bytes 15 files changed, 73 insertions(+), 299 deletions(-) diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java index 60864ab4ef8..a6f3017d02a 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java @@ -96,13 +96,14 @@ private BuildHintCodeGenerator() { /** * @param args annotation source root, the catalog source root for the - * generated binding table, and optionally one or more markdown - * files carrying a generated build hint table + * generated binding table, then any number of further outputs: + * a directory receives the simulator schema, an {@code .adoc} + * file receives the developer guide's table */ public static void main(String[] args) throws IOException { if (args.length < 2) { System.err.println("usage: BuildHintCodeGenerator " - + " [markdown-file...]"); + + " [output...]"); System.exit(2); } File annRoot = new File(args[0], PKG_PATH); @@ -167,9 +168,7 @@ public int compare(BuildHints.Hint a, BuildHints.Hint b) { write(new File(catalogRoot, "BuildHintAnnotationBinding.java"), bindingSource(byGroup, enums)); for (int i = 2; i < args.length; i++) { File target = new File(args[i]); - if (target.getName().endsWith(".md")) { - rewriteMarkdown(target, byGroup); - } else if (target.getName().endsWith(".adoc") || target.getName().endsWith(".asciidoc")) { + if (target.getName().endsWith(".adoc") || target.getName().endsWith(".asciidoc")) { write(target, asciidocTable()); } else { write(new File(target, "com/codename1/impl/javase/BuildHintCatalogDefaults.java"), @@ -647,78 +646,6 @@ private static String quote(String s) { return "\"" + esc(s) + "\""; } - private static final String MD_BEGIN = ""; - private static final String MD_END = ""; - - /** - * Rewrites the generated table inside a markdown file, between the marker - * comments, leaving the hand-written prose around it alone. - * - *

This exists because the file it targets is shipped to coding agents and - * was hand-maintained: it told them to set {@code android.xPermissions}, - * {@code android.minSdkVersion} and {@code android.sdkVersion}, none of which - * any builder reads. Generating the table from the catalog is the only way it - * stays true.

- */ - private static void rewriteMarkdown(File file, Map> byGroup) - throws IOException { - if (!file.isFile()) { - throw new IOException("No such markdown file: " + file); - } - StringBuilder existing = new StringBuilder(); - java.io.BufferedReader r = new java.io.BufferedReader( - new java.io.InputStreamReader(new java.io.FileInputStream(file), "UTF-8")); - try { - String line; - while ((line = r.readLine()) != null) { - existing.append(line).append('\n'); - } - } finally { - r.close(); - } - String text = existing.toString(); - int begin = text.indexOf(MD_BEGIN); - int end = text.indexOf(MD_END); - if (begin < 0 || end < 0 || end < begin) { - throw new IOException(file + " has no generated-table markers"); - } - StringBuilder table = new StringBuilder(); - table.append(MD_BEGIN).append('\n'); - table.append("\n\n"); - for (Map.Entry> e : byGroup.entrySet()) { - table.append("### `@").append(e.getKey().annotationSimpleName()).append("`\n\n"); - table.append("| Attribute | Type | Build hint |\n"); - table.append("| --- | --- | --- |\n"); - for (BuildHints.Hint h : e.getValue()) { - table.append("| `").append(h.attr()).append("` | `") - .append(markdownType(h)).append("` | `codename1.arg.") - .append(h.name()).append("` |\n"); - } - table.append('\n'); - } - table.append(MD_END); - String out = text.substring(0, begin) + table + text.substring(end + MD_END.length()); - java.io.Writer w = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); - try { - w.write(out); - } finally { - w.close(); - } - } - - private static String markdownType(BuildHints.Hint h) { - if (h.type() == HintType.ENUM) { - StringBuilder sb = new StringBuilder(h.enumName()).append('.'); - List v = h.values(); - for (int i = 0; i < v.size(); i++) { - sb.append(i == 0 ? "" : "\\|").append(enumConstant(v.get(i))); - } - return sb.toString(); - } - return javaType(h); - } /** * Folds text to ASCII. diff --git a/maven/cn1app-archetype/src/main/resources/archetype-resources/common/codenameone_settings.properties b/maven/cn1app-archetype/src/main/resources/archetype-resources/common/codenameone_settings.properties index 33d9b8ef65d..8f0bf0d6d5e 100644 --- a/maven/cn1app-archetype/src/main/resources/archetype-resources/common/codenameone_settings.properties +++ b/maven/cn1app-archetype/src/main/resources/archetype-resources/common/codenameone_settings.properties @@ -4,14 +4,17 @@ codename1.android.keystore= codename1.android.keystoreAlias= codename1.android.keystorePassword= -# Build hints are now declared as annotations on the main class, where the -# compiler checks them -- see the @Ios / @Android / @Desktop / @Build -# annotations on ${mainName}. Setting the same hint here as well is a build -# error, so move a hint rather than copying it. -# -# java.version stays here on purpose: it selects the toolchain that compiles -# the very class the annotations live on, and the project generator resolves it -# before any code is compiled. +codename1.arg.ios.newStorageLocation=true +# Modern native themes (iOS liquid-glass + Material 3) - opt-in. +codename1.arg.nativeTheme=modern +codename1.arg.ios.themeMode=modern +codename1.arg.and.themeMode=modern +# Desktop integration (only takes effect when the app runs on the desktop). titleBar mode is +# one of: native (OS title bar + native menu bar), custom (undecorated, CN1-drawn title bar) or +# toolbar (legacy in-app CN1 Toolbar). interactiveScrollbars enables grab-able, click-to-page +# desktop scrollbars. These are honored by the generated desktop Stub. +codename1.arg.desktop.titleBar=native +codename1.arg.desktop.interactiveScrollbars=true codename1.arg.java.version=${javaVersion} codename1.displayName=${mainName} codename1.icon=icon.png @@ -32,11 +35,6 @@ codename1.ios.release.provision= # See the "On-Device Debugging (iOS)" chapter of the developer guide # for the full setup (the IntelliJ Run/Debug configs that come with # this project's .idea/ directory are wired against these hints). -# -# These have a checked form too. On the main class: -# @OnDeviceDebug(ios = true, iosProxyHost = "127.0.0.1", iosProxyPort = 55333) -# and iosWaitForAttach = true to block at boot until the debugger attaches. -# Use one form or the other -- declaring a hint in both places fails the build. #codename1.arg.ios.onDeviceDebug=true #codename1.arg.ios.onDeviceDebug.proxyHost=127.0.0.1 #codename1.arg.ios.onDeviceDebug.proxyPort=55333 @@ -49,8 +47,7 @@ codename1.ios.release.provision= # bundled with this project, or with the cn1:android-on-device-debugging # Maven goal. See the "On-Device Debugging (Android)" chapter of the # developer guide for the wireless-debugging instructions and the full -# adb flow. The checked form is @OnDeviceDebug(android = true) on the -# main class; use one form or the other, not both. +# adb flow. #codename1.arg.android.onDeviceDebug=true codename1.j2me.nativeTheme=nbproject/nativej2me.res codename1.kotlin=false diff --git a/maven/cn1app-archetype/src/main/resources/archetype-resources/common/src/main/java/__mainName__.java b/maven/cn1app-archetype/src/main/resources/archetype-resources/common/src/main/java/__mainName__.java index 44d6a1a1b39..a415a02bd87 100644 --- a/maven/cn1app-archetype/src/main/resources/archetype-resources/common/src/main/java/__mainName__.java +++ b/maven/cn1app-archetype/src/main/resources/archetype-resources/common/src/main/java/__mainName__.java @@ -4,7 +4,6 @@ package ${package}; import static com.codename1.ui.CN.*; -import com.codename1.annotations.buildhints.*; import com.codename1.system.Lifecycle; import com.codename1.ui.*; import com.codename1.ui.layouts.*; @@ -15,19 +14,7 @@ /** * This file was generated by Codename One for the purpose * of building native mobile applications using Java. - * - *

The annotations below are build hints: settings the native build reads, - * written so the compiler checks them. A misspelled name is an unknown symbol - * and an unsupported value is an unknown enum constant, rather than a line in - * codenameone_settings.properties that is silently ignored. Hints that have no - * annotation yet, and open-ended ones such as android.permission.<NAME>, - * still go in that file; setting the same hint in both places is a build - * error.

*/ -@Ios(newStorageLocation = true, themeMode = IosThemeMode.MODERN) -@Android(themeMode = AndroidThemeMode.MODERN) -@Desktop(titleBar = DesktopTitleBar.NATIVE, interactiveScrollbars = true) -@Build(nativeTheme = NativeThemeMode.MODERN) public class ${mainName} extends Lifecycle { @Override public void runApp() { diff --git a/scripts/copyright-header-exclusions.txt b/scripts/copyright-header-exclusions.txt index 0ef1e55292f..77a600506a3 100644 --- a/scripts/copyright-header-exclusions.txt +++ b/scripts/copyright-header-exclusions.txt @@ -27,4 +27,3 @@ vm/ByteCodeTranslator/src/cn1_sqlite3.h | SQLite3 Multiple Ciphers public header vm/ByteCodeTranslator/src/cn1_sqlite3_amalgamation.h | SQLite3 Multiple Ciphers amalgamation, upstream MIT notice over public-domain SQLite Ports/JavaScriptPort/src/main/webapp/js/sqlite3mc.js | SQLite3 Multiple Ciphers WebAssembly loader, Emscripten generated, MIT over public-domain SQLite Ports/JavaScriptPort/src/main/webapp/js/sqlite3-opfs-async-proxy.js | SQLite3 Multiple Ciphers OPFS proxy worker, MIT over public-domain SQLite -maven/cn1app-archetype/src/main/resources/archetype-resources/common/src/main/java/__mainName__.java | Archetype template for the application class of a user's own project, not Codename One source; a GPL header here would be applied to the user's code diff --git a/scripts/gen-build-hint-annotations.sh b/scripts/gen-build-hint-annotations.sh index 0ba5d0e386f..fd63b45b109 100755 --- a/scripts/gen-build-hint-annotations.sh +++ b/scripts/gen-build-hint-annotations.sh @@ -32,17 +32,15 @@ check=0 echo "gen-build-hint-annotations: building the catalog" >&2 (cd "$REPO_ROOT/maven" && mvn -q -B -pl build-hint-catalog package -DskipTests) -SKILL_REF="$REPO_ROOT/scripts/initializr/common/src/main/resources/skill/references/build-hints.md" JAVASE_SRC="$REPO_ROOT/Ports/JavaSE/src" GUIDE_TABLE="$REPO_ROOT/docs/developer-guide/_generated-build-hints.adoc" java -cp "$CLASSES" com.codename1.build.shared.BuildHintCodeGenerator \ - "$ANN_ROOT" "$CATALOG_SRC" "$SKILL_REF" "$JAVASE_SRC" "$GUIDE_TABLE" + "$ANN_ROOT" "$CATALOG_SRC" "$JAVASE_SRC" "$GUIDE_TABLE" if [ "$check" -eq 1 ]; then targets=("CodenameOne/src/com/codename1/annotations/buildhints" "maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintAnnotationBinding.java" - "scripts/initializr/common/src/main/resources/skill/references/build-hints.md" "Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java" "docs/developer-guide/_generated-build-hints.adoc") if ! git -C "$REPO_ROOT" diff --quiet -- "${targets[@]}" \ diff --git a/scripts/initializr/common/src/main/resources/barebones-src.zip b/scripts/initializr/common/src/main/resources/barebones-src.zip index da205fa34873e76436d9de37f5f7b71a6bdf1184..6f000dc9a5194aabf4c97420dfbee7ffb6ec6adb 100644 GIT binary patch literal 1327 zcmWIWW@h1H00H5A{}?a>O0Y7>Fk~f`CF+NUa56BLZJC%^0mP*h+zgB?Ul|z~SVVvd z18{2RglSLC&n43cL1ZIRD-v@Ha#G1ON*tR}xs{0p1q2NQd6NSiI&8~Rj2;7hewLYm zK^3=wzLkyz1%8RSsd}K`gNI)7XN=IR4ff5yZNRhlcesF^rK4K%0Y7hPowHV3vM({j zHpsCbU6!0UN#lj`I>Rsf{rm2!9G&ng!Q)AF|Chxn6(8H*3vdPT#P2W?nwhoJ@Un{F zsR>^n*nD4Pp}?gTSll{4QXuE!iDQ?|FZ^DUJ=gu{v_*#&>8ivvxK8xuGE}YfKDfJE zz)^lepMo z-P^Ig@}9}rz$qrj_MWZd2??okhH; z?@{M9_3}KtFZ>06;NsIfM(KN^4C1EUlzeYf*;Tfp^5V^nA|Hc}7N&5_PqTdzs~%X` zUgxZ`{Z88Az8zhQH#ePT)jV3db7B0&9?@4Hu3ekpp`LD*QNRAt5fpM85-x9`v1 z9lK*~d>));(F-p#HN7cN{)Ea!tx|O!*S(ENDu%sD8rIQIUofNO;8ZP+zc@sJ%8e| Vij@s$5(6s`?gSc^0L=6Z3;^vO0WXyti-ZJ{Q#UwIAKbX^K)T9KGrkdul>xi~iE zxs{0p1z=4gKxqyJfh4imYYU|^f|(f@PO>pDsN&Y-Tj^L(;Fp-2st58;ZHRCFZ3}_D zzr%TIG@cw-y79ogS64b7@9@~RjalW`w}=auZYVhwa@0i#iv4|WJ>|)fo4Jdc6^ic7 zHm{NCo%(aKjlz=<&YEdcuWGDvi?WvG2}wQ4`oWQH>h_K~Tqc_i*}H@!Z4?y0Ec_xj zM9R6-^;mao$S#ekod05XDnyY)`JNWWv| z$A)=}PG8(?Ik~%=G3LOw5V>z&%2zHOX5_V!+|UrqJYC4E{rCFAMl7%Q`>2)1?pIN5 z{uArlw%K(*^LI9V^&+A9-?o~_?5+*)ylk>_`n%ZiNYAwQRGIc2?C@fXVv zZ@HxjVM=kgZcYoHdzbx9Krrv6#OXq}R{vy@b57WnzqGoS??HfA-JDHV{aPE?Y_@8w zyI;i1_etpU@@bKrGn|+1*}lT`_64~f*-31RDvd&ncdjg35^R;(rT1X5?>ggu8l`{q z8GYA8oGy@`Wx)1r`;jLC&MFzH68S;9jI-7oL@Vb-Q+Ku3xf;_xr@VXV%_T+5Tas^`;LWjBFmvXZ%oHTAwmIr19-4b@`tT z4;CdBnZ0U!`O|G((*4M}xjErCKZG6RFWM#1_i)y{@V6y`zGhOs@fp_*S-$Oj61V){ z?$Z}^E!?}lWS*;7Dzr&slkvUE52fY{pH=QUJ@pai$<3$EV& zHs)$Ykr|A2w9NgA`fl;b&6ImfSM|NP_x`@^yub6F-|so+Jm-J@&-47x5Lb!MRch2F z66CCp%I$mgjCw{%9zo7(BM1Rmfka0|S|mqC`0QMYfGzK154&MKA(@2W@W0{^1dm|t zBwZ{&^iFkl!mw&M_?lDJOTY0RN@0hb zwOBiwoiyPk-RU;AKki3WF*mn2@mPee`^)chCv9g>tzcfHZ=rt+wZMo}lRJ2z5W_W|OO$#AW>|<*${!`P;L* zE?p~sZ!}YD6@BTN=D5O&^MT3*&TN~tu0^emXDE($FV(g1*q=|niHPZwR920ideqjl zmzg#tzbPyKlM?=<bDVVf|@Fj;g#d2VB-nJHt*^?v=^8WR`lT5u*VMe;?= z$x-nn%i+=E;ydgRF22|GpMKjq4WC4gt8fgAb8K0&OIB?a*Q`9)Y>>I?)ii!^WmRr^ z{WwcZ%)frf;HsDCj>xDX#LKK>MzUPt<1HHgm+%zzz_j7J=UT$6jdhhr25F9#gO+=D zSWSP4CaX5s7+RaBXiL*;1Kd6K|HI+%LuUMYD?jfmHx2UN#Tsk>eV1C|FSV= zf7CfE{P^;UjPObOYiNH-eQIn>Olqo!1yL;eoSDG~@?aMwi>nFBTGtB+NTYi5wHl1hO8#+qd z&9wdTYrM11Ykr+pc45jv2X1hT^&RH;r*ws|w95>`I#(0#M)>ONk$^N zGun52RG%1n%6{eMTJh_lTV-*Z#u($vo%NUQ3qFk>ikz6-8$$JeB`(C zWk=_V$!6td8yq^KthPg8HfO2EQx9oG5sT^cZBp6MXUcxhnmuN1M;+=@;*=F+@}!Uv z+RVVcV#RA;p2#K+WNlQUl*AVo^Q+t1%B81Ga(umaoLDU=$nTGzoB8dQ{taM5>S$IrhMpU=n-6wn4crx`IW#fBT)noDnKxS9jd4f*<7H*t|pNMDRn?o zvmP}j3M{I@4pboKf-5K`y<*0HUiJQLm{uYYVT^=i8WeT`Q_{RWHi2RBeNa41>jo>J zT{8|3b%lV4p2R^@Ay|V};h?_|Y#?mK*vXzoc4jQL6t-rWeqV2@9L%e`I9Jeme=ai@-W! z34(^IG{E z&NVnBEGlju%34%~2YY&f6~TtLXzUjPEA#*lZWaSa^db+Q5Mu|5d9X{2Eq1Jjb7HU_ z_2R>IePA7$$cKmefR4d`JV@AGjsIX_k-XGA081`|Rj{`Yn4-H1;cOq+fHDi=+J3MJ z2}Xuu5tQ`FL8|cuy!d@9mo|?Ps)*u0qi%#`IRqZ=1PtSk3a;D|QXX3Luaz}cQlaj{$ z<*!DzHq767*1h@F4ISgN)7_cL+PBwjHQ^>{+;9nCW*=6p$XZPMy_8as^TEMnfAUxP z_uL;XwoA1K8jF&*HD!fgNgsC95X~6bB3vQoe@=)?aNs$*(e`-=2M8(fC4y=*2a{Zq zG^fj4Jxn#F@43Z$d-V><#mSK-hcmuJ+0V6VY+5$Cd`2#`%feqd<#_n$A2SVA?ELif z*`q>SXFYnGP3JW~bYGMTLoGQeh_~lTx4V&QSWv)=57x`}zU*C+iOQi5$5S+q>UjIL zopVbI)xOa-^_F&SaA|{rPxPDM_v2em9mu5bP7!pfc9jv`Bd~7Q`NX}tOl98ool+Lx z89|JR$Gf!Xy>4dT6RMr9RW27rzb&ed*Cut7ALQm8CO%hE_UK?ROLE-VLsi_R=(k}f zTb&j?(zM^?&SlOFxg?7J@NvCf#-^TDd*_j}Xdy%M89BX?MvMP*NApzf527oBJ`^na zsp;QVjrkL0l4HFM3Rf4JzYX5bt}Tw&Y?Z(}>_s1hNa0L$6%CE+++!D=@fHy#^xc2F zG@IQre67~0%4M^Ln)|%&t&SqXcbZ7oIq9vKlCs(wKrN85afg= z4XDam?&>k;v>>DV*BfVTGX6Cs!ZhKD5~X^uyKw7vTS^E`%Q-{SJx!L(?36D>M?->5 z$L6XemtJ1|BrC1DEz)Ii6KxB{+3l&HWeq)t9mkb)&jWVn!$iGnJ*mzE91(O>jyjd4 zwb);zKGJs~W$Bmbb+h}ZEl(~N{I&K%d@6}NN3|<64~#uKUyye;Y*|k!%4H-He#xdD z2pGTxzpMWI`UZ_uPTy}>r}V0{)Nv^);_1Y%HM`yQ-Gpx)v}~KOnkq_)NLe>mL)CK# zWq;0#JjL5uZbtsNX(PKKwScSQcuHoE(k(~-7#dE}l%_H6X<+Jk%V1`F>XTH!^)oUr zmoC1uJmIpuU)1#QiQ&p5TS&|(QG8{5Rxt6^94uS-{AI?ZtcoyZGhz1KKFPa$eDT}+ zdRH6Y$C+y$dFPQY=#kxwUpb4eAJ;0p<48Q7w3Pm2q3Jp7C02q3ydQz1BJTU%*tcnN zU;7JBe;b--&@k?#2tMw0Oq+CI)X<}l?$Go6Av{T7NvuzV9Bh|xU7KwpzW7V~<#;8+bl|1oH+4`7IqD7y_}8nRL?N=;gu zH{T53d~f#rk!gOSMZq9{e$0^XVO@QBD_=N}x1BO-Ub$zjxn2B8`u1Z1AKMf8_oUa< zx^f)E{Lb{&hHu%cxS63&AC#JLc&L}>K{_#iFYQpy*rAs>J_`DFfv3~p)mEp586&B> z&bxYi`fMfWSg^lZ+1L1^%&Woh<7GY4!#zXg{NS|Tw1sAA5Z!W;2_EM0_#mFM1U?CTn zqID{8go}|4tH6kIoD|gVz!c$CR{^yHqqqJCh`{C!OvoVyTOH<2^ZptO61xEz?P0;FZmLH=P>VmS3*j;XGbgCgkDgJHiSIMM^8VQmiAgT*>|HTH{Gx+Gj}jw~!Ld%T5x(xlEc43XbT80D7t5ex zACQ7?o&!}>wHylbfHtH(!))91VcX&=p+_IsB(Rc-@FWiqM2aiH-$@8{c^Esl5__C-SFm(Vk;lP5e1HckZWI>_lzy^KDg3ix@t-=xu{LFAi UTfvpbftX@l6OSNS?Epjn0rK{?1poj5 diff --git a/scripts/initializr/common/src/main/resources/grub-src.zip b/scripts/initializr/common/src/main/resources/grub-src.zip index 524d386a3f907ee1802568f0906eba108f788e80..4df7d0b9c3b591ccb1c12b0198b8fda1d9e95a5f 100644 GIT binary patch delta 13701 zcmb7~c|26@`^U#QV^4P3ce0MH>}4q>N-0!C3rVYNAu^UMNtTp@h#sOMTV-jpW+_ob z3n|o7c29~T`OTRbW1R0C(@!t2{<+@Q^|`NmIp=(CVV}8X&v8Rznt-qzBSsW+WdEuC zYPL4481PL=!r^Yhua6%)h5`G70fWKvVK5kCs3PlpsI&WV`r#liMidGO0Qf}dWfo;1 z1`017*sB2ugW{x|5_-g(U9{D1vjmB%SunaMw(i+$g{#QLVlY1J7|cpC4qep(SV`sJ z9F7zJGvcybEua|73n#b~Wh`mE41?j;CM8JV#wy?`^$+|n``p37t4muTXsXb7w!~Yx zJt@)q&|s;9*+sGA2RF$yJ$E^E%21tkQ8w^&^{#BpOHCDU?4L?}02={N697M;`=Z)2F#gmWC* z*nk7SR#|V>@@WlR@t^)WO+l+oc}63#O(!?kzt8J+cWe`nT^kbsjpe*~chq;~8|^c% zuf(5ssdI_bMAbR zvq$P!6U^0;x1M+{&$4^pTib! z@0kSu2*JbEoLvkZ`q{1?=5Hj#*|~)VOy$NZS_98Am_$UM#$&3&KM#hPF(;l_c0_imBsG|z*0w#@$afK39fe(+_*Aj#{$}YYljpM++&hx zoayxI7T#=>1{Uu&m)tj{64Cce-B_r~E}HGm2Aw@V4I{qBA5M1-P31^L*|2!Oyt4d0 zZxl02jDXO+dM)Foan1Y6^-fZ@N)748GB3Uj~c(^*7UQ=H7IYfRrdL3nZ5Fm7j4`2sSNS4LPYU$CQ@IrLFMEl){O{gRF8Ay!oZ4`VVPl_J zEjXO{6R_*Tey-j4s|wf?yfewp{$$`WU8T-XQ&ETWUn$fyRhyVUGSJ`1oh0%zXXwuL zSEGB(%Dyl&b2)5JN$11iEec(@f)n1mw@zL3VmNnT!}~N~r8Kz0`*65=j^WXo$(;N0?)5LirS4m<`($A=#8&%!nn9mI?yg|8R`A%P z?8*?iNv;juk48t_B1;|Z&gQ6RYJGh44-k3?vJS>+8lG&}{LDP0_Rc>1wE39g=`5Y$ zoVQaCU$_c6#5Z@IF;C+^?%`u!$nmqOYqWBWv8rTq|JjfGJ6A$n3h_TUcpuAOc9PFn z&hq;}?wju}wR}USPsa9_YzlZ7Y`x*3x#G-!yxi7YHatBRtYMB^8MhuNr|||!YYDsA z$@V0(O|_Zl6)A zKb!J6=JqdalyQrPU4WtUkym?cS+kj7yK0Uv(0DK4W6PXd;x#2 z1LHCIYLs1}aPmfF%%frv)!w;-EbVtg@9h*Haq>*=%zwF2{b-e-^Wz;B1x0L{8=In@ zNNkQ?Ze#LA^8C19KBqjB-Pt7Ftx-mjb#=G1duw$;L84C6{0_TyvE9a zcUSTx_Tqz)-i{j|(ogBg4|522)#68Q6m#-)UV7SkXV>@hJ()WGuSdG8w&S}Qh6nuK zyb(^Ac^UFERQXY_!nvMwE9>uexmpo&E?H@Qll^g*>cTU^M>y5oCE0|VZhUA>%NJ0Y zkjIGdJ6A?r?E(WGt^nqG+UkvcjXi85&n0Jv)Jh^{Ma(y5EH6D<@Ny$Vro})v-rL#c zQnR*$80(1~-4EFV+H*4j4n;1e-JjMw)HsDI1&eOc_7vL_ptC)@-Ze_B!pqfhShS+( z>)zuW7G0HN4L$W{7~HRP-3Z}R>s(^-@*VYlY2B?!v#R;Gl~wJx=H4DIvM#hY=t|z| z`hf4L^V;V!mxViQ6`=&43yoHB9i8}_X%%a;oK|-{)ol3kZAV1;^$WRzDn|N6V@*+g z9k&t{PJfq9J+ZQ@_1ZDqrZb5_MshnY5B`a`z#pJ+{$Bwp{(*@BT-BB;@tK`$_Ul@h zdH?jd%w_&^viT5tpZQ6lOT?xrFjvEe|h?#wyx_a-UKaMj#$-79`bOGvHPQ9x?$7F_uHBi@(#IG-3)GhJ!&NK z>3J4DBv!8(tMM+c-PB^gw9*^h;$!vphqYIIjVm4r>M@-sA4CQzE}7QbV^8e7biA)A0iTw6$S>!qfXZP6=@6>+1U#--&P ziRDZ$2leH0yOtOJ^qb1co4u%6w@QRVf7@nRiFSMd4vf`E4ZO(pAYWuK>1VRqKw5>w zx|koYe|chxti@kc*VZ@^;a9DBG*mr9;lFhnSA_@HPm!i zRaC71Pr4TWKo!i>`E$X2w7g+Z*tBL?<4}Wy%*VIoUuN2KXAVi9QRetF`>k!6s^l-< zODqX$c>jU%Q{f45H&0gdLC}bfk{^b_=Si5sqfB4Bi?^TdvKn^&^+fi#S~l}F&a6Vo zqh>#zSlI6kAD>!RIR~g*eyT0+u^^4sFLuTI^gI{uK z^F%}+>*~(UT+1qP=X_~hMu&TMmRCxX_mes?#nbBrdD9Wsvi}_J0R!|`dv3ar-{rj7u{+7=mVtY9a={~P+|BbMV;g-| zGD81M*6^KUPhZ{N^3;Ua*Iv*4&6G@qLtOXj{<^ACAMwgN_p9*E#{&I+?KlVRw)7M>U@4mM^mXqvs?ENnOf(xfAMNBIVYJa}hS=-`* z=es(0m)S2Rr2ec}lkirdB&qe8>MzFDxU7=^+!TgmI-Nd>vx2W5zkRmXeZ5p0M{>1q zT{~m8T;&Dkxt85)x0ivRd&kY!-F9{PS~t=f8)M2MGkj3e{czFEXngfm35zSOiM(z6 z-vtCXb|{89++ulL8`;DK8u#-CW;}P}OXk>U3b8^qx_+Ni%JhuG)(qn{CAE@OrJpSS zrup8pw~W7oJyTO9NO4zvuoP5Yns>?O?S;ziU2y`LwcDO>3XlKr`@MRH=efB&$!xD9 zlD&Mo7}wYDbu;#_{HooB*UBys%aS|P2h6ruzP@Cl)m!@^$%(zNJ0P+hvuS)%fGL8j z_)OH3(uRxdQ9DZhN!^yb|8}_g70qK?KTHP*Wh8ux58TMZs#T?NhqJBU+v7Iyg(a>i zC|o@MRzgmfP+ZS)}vY zO{TWyd*71^&JBJ^EE+lK%={^s&3m5CxR*o}Io#LO#BDxSgRR;0kv(Pg?dHnB7_r^4 zLJgY+cL=U9OE|5}HsoflC2}+{Y_~f1hS$rRy;F~w0|`4)HP({2w32URD-@sten zT}ip$Z>-|~8giKZP~5k~NE-~(?phn zhxYPd$scR*N0Gz-e%O=^ZvYN4k-paCq0?LDzwOY%W48b=!1-`hUaY{vCl{^kSFC~e zl<*8&fO{c)4-GLzwm=C*%rq~SDx6mK)IESHc3zAVA9lq;c3R=W`++)&m_|N&oe??+ zU@6(v__52E&c6LH@QxB5&yVF=I^6jLAWaF+_XGr&4zKeBA}Qfc0$ARq!^3@n8S+r| zmX5q10GwbX^w1*&Q2u|cHs&Mgoh2X!!^ncc7!g(*0XJSKMB@v(tT+T{fhEC(puBME zg+?p9G8~YBmjW?-pCDFzA^UzBD@P>;$b4~r2tg2XodHr08Nza?dgEfLUvlC7$!u_PXgOa#4^t}ilq>sT1d3QMG66b%6PwtQ12NU1Aqu(M9RkR0Fe|$PNG=; zB?k>Ns%4+c06z-zOqAZBGadlWi>G^y7##+#v$D*+3OG-xlP881UC>6uGJ**6CsO8E z2NY8n;;azX7S(>G)i=9FU?+Jd)u8v!sSiF{;iJ!iHn>FfOJMzyipm() zVx*L@iqI$)qm+ z!AqLhO|caq)loq!Tzdt0j?$TO87$dqg`eBB!so=mTuOMeEJ){J_D&YWvCoUase@Ec zRvO#B%uF3z4<9N-?S(oZ)sCn2Ag3YTC|z^Xxo zCg8HAyZOKboT7~PjXB7(5Ke0VgXW+;CH%ZRJu&`UL37F~9+t;aJv3;I7uZGB{8lHB z&QN=tz&3L8jTU6nN<4l9bcbaVnxeZ9N$Y?~_5j5x6WSdJQf(w!i3b9~36A+08dRX( zrnJI&&VzlFgJZKIy?v*i01Cje2^&cXs!*iY?O+HDr>rjJ40`R;&j7bkb~Ry}(mBQI zazQ)FTpAaFR1ZX2D`iI!xQCpb&YRUhIk=l5J71aJ;Tuo|&QN-oR!_Z$XzhpMdQfpb zdr}KXHAq^jxmv&q${-0xHPvH}R&w^&U=>A+xhnMp(a2u<9^`_PbAJYv7FHpRM-pW4 z8H8_!;6R8GNBw$FYt1Hp2D#uzT`wb68EXAXeP+=Jhu(h$8|IUbPk~tZt)4CiJ#p|& z809%hi~BPLij_?dfIP%!yc(gFo*MPBPJ=01Hv-y`!?hQNOe^xmICuh%B#c=Znp2}U z=78^@1vy*^B8-CSoTinXpk1C4zIBFrYtRaJngPWq;W>Zkh2Q%FHdDgkmO@1UmT}4P zLIg!>WuE}-Z-6v&YnBWz6KBGzQ%d-=((C(KR;&dG^=klvN^FFyOV5K|?mnK*2favl zm+-@n#X&aC zLP(+Tg(o3YVxcjpp)#aU*}n)?B8Nhm0RZz~#H*3w)#--9y(7q#gYqWXmm^wZe94IwR}~~&M#Dc`m=P2BfAY;WBkATEF-H&q5!GVFP(w!Z5NW2C06BRV zfuWFz79b#KYqJz0vWf|03=Bajb#UMa%07plLkb%oX2E` zoF);(8}0Q(bu_STmJEP62;bzB?!*^gX;Y^QWg-fIiny_?=qiZHU)7S35I~N`_?+?AiVGG|tQ!j%+0SF;+Vp24lQv8fT)Z za>AY-`iOc(5#4wgN5vAS0yg;mTGZUmd&)(GwIxM3CpRn-^&*ifF>C;$i)s)ijRn1I7Jen7ko%!VLuTan?Yj9 zH6#r7711$!DMYmo&G0Y{>5VWS3od@WXz3u8E6OE&NWpF+dQBB+M9tK03d>G(9qCnP z;6YS(=qF_`;sN>53(p`6+kS`T zqz8|yfr6aWZ@c#y2yf4@e+|2q^k@$q1ih1$Ov5H7J=#eRLGNQH(-cn=y=BMcu;Pn^ zhx0Nln44xxzq>BH_DBCHfYuUjeMPu280|#|-78_T7})(p*P$nm&=D#{=3pBXol8Y> zB1&Wq_Cx8lF2M=WItdLj4cnvWRozx1)S9j#az=mMut%%?w*!Q~8nR|r2X7^-h8i5yD_LTcaY!yEj9d?PWB+<$jh1PgTtj%3R20HsbQewR zni!%EJ#^{z$_VMhiDU_|Z;Q@VB00lUG6x&D=$yO?qTa)6Bo20R>CJ0#Ct_Y3Zjp<^ z#x8o%No3K_MPv?kc+oldm4aJw(JRG<3I?Kyiw+g2B1U+Vj1YZabWQ+=;J6<#EEvG( zTp*IeJtj$nO;oHjwG~WoduaG6P%kn=Ni_rHF>eRco0O1o#H2VpA=29Dl5^D%Lltcz zN+#LF=p2_if~#y^7%JTd=CT=tQ2iHV8n%zot9Bu)-fkyzu#b$+nP?!?w!U6aOEQ$v z;cH0PqKmj1)}SNonuvO@ddT%)cNv|7SGhjhqE#N<$FRs@roC`TMqGl*{A&ookt29` zEqx3`$9d_3y2}?8RO7``6{Ogiv{ox|QwlDkeR;7&3wr62+>71GCK4n;2a;J-Ns5nH zNtO<@*i;E3LqvmmNpk+Zh~x?PkvR1w5##}7$xl*9G_C27xJ6?tm?vTT8i)QG#z=VS U!e9;%{=LLuFaiREFJR370p4L*g#Z8m delta 8865 zcmZu$2|QG97oKazPWF8#+t`<~%a&w`6tZPkB-xUP$x>($jsBMw(LzO*29qUZjS{H{ z87dVmB3ldk?!7ZIrf>RHbKmDV&pG$pcgAyG%jsOn?>Rv=9*pn?78D8<5fFLkaD-n# zq#F42Eg%Y@z(b}Op;XCt0Q8rRDESVpq|QlA^E-4<4V2==2%`m2C{W4_BSgLuhpsd% zFcR<;ECapYNJg+^WFtO|hmpLZMp*&J%rR`_B}MWQmVBkUO6WDhuw?-vj3`vFPqdF( zrZ77*R5bD)E+kW!jt2!6NMiV)cS6WJ5k!Gb9J!Fh#{!}-F3Ic^6%?Wh2NH&X3JkZT zFTW?9s_278b`)w-7lo3i@EaJIaoz6jk;9w$6Bf%%mV0mR%5B&<`Lxwe=hQ}np|11W z&f`13e2J0dKF_%e#d_TNW#ymv9>6O7hJsBs-fqsDXY65WWQ*SYnTbL1qn5&&dligx zh2PRMj?euVuVgqZ#S_(TWv_0wHD)8<8%rL2@!7OpEtU44c3OlO*zrEM9jWNWZL1GF z7Zqpj_>IjyzV9) z1CP>`oW_+1%D828U&cmT@@q-~e7$~;s&*dB7L?QyI;SP{eTELpDbFRftJPLW!?s&H z%g_D(#9lnBT+TJF8f!}~4y#l~TikxjshmC!mI&(`Y5beaHoa}Nx>2OO@%o9ay4&&? z6z#`7%(lHSF}TXhC!pCaPgh0XeZS>e*R*8%E$RI2y?5pGh2nh^r7Yd1mn|)-GH&Ni z@hog>^0lz6-P36xevi}Vcvjvu02Sure%R#ti0R|Ri;DDTF^QMkc884(`wMSf#+BZV zx!I|ne5p(K1TgYcZ%=Hi)wMz0^k9raXX?VV=eO9jJ@ZrBz88?b4b-)q+h-C|$j$Uh zEYjf^|F%cy3G1Cc{QFNnc5a;6F!A}&@RfyWnJkvXr^79w2T&`hjGgi>^Tzi(4;PW- zT?UqmN%{1j#MGirSqWY-+VF4(^Vu6Yd)R9mJ~)o#aT&{*T@=n$+R%^}+bJhd zBIW3gNjO_?2w<_HGMR@^UweKE9`BJ+bUIsqVFDHF};^M~K9dpm}8b_4* z^Cq5O-nY-av*x&oMj>E9)PH5f6&NRiOVd>zVqVT5{0ub1Ha&XLxy3q$cSqu-?s1P_ zVtRwqj?c;^V~tKq3GSJ0zZct4UCf{&`0NsI(p^Wp%9J;O;T%_vb7KVuC!1%T`xf)> ztE4b5mJN%LTI%fFQe46EQMBCai7>xBq%i+!owR2`#n=m@g|xz4G52=v4z*wmV->Qx=R$yG)m%>rW?RH0S*$ zirZG>X7d5rqZ8)#3c7{U5;BqfcfG0;F6R)0_n;$3EowypL+=RP$GjPCgs@wRmGtLv zXE&D9?WN!AJD=s2q$qpgbjYD0$GD_!MoVm1ZAO$izFy8!wj}W2LsbpEMmZDxC#O~d zI0~&sk{{?C?jV9iwx6-LF4>L>3&p9c$}I2)ikEG7+hluSDK!37!ss0?5kQKR%*akB zx*&5Ws!LGPwQTls>R`s0(-9|Zlt`V00B$Vgq=yMAWsvQM_pR*#y3$t{nU*}}%7X?@ zdX=2!YfRq0d$aaaskltZon6NDa?*=#K#XBxb+&4(?g^JuTRl(gPM z+~81)NT7AM(*=`glNk~3#Pr>)nm_KwAJ+OZ;?X}ma*5+>C}9z>d;G!a#p1Ph>LJyn zy*Bzi3@>%dYumAWLleq?SkR0q^BCajBFns zpwUWVHkajFB{<)*nagWcYx^%eb~LJaEPk2Ce|~SG{%@6$9dT$Ywu6b|3D=JteHp~= zZo^kyS2gc*#9^3$`G73nhf90rW}}HlF$2M*ChqD{%om?V7k81Y;b)0IE-O6<+3EXW z6HZk6^L!wI!{)l1-gHPuqa%0Ze^TG4{ES z*QBciS2V6;(1YbQl8!vvAwkKf`vzzUt}PE=xk%- zfRGK(TTQtk?gefqV0^!`%s|Vg02T8)DygqCW#<50`#5C|tahvOA@x;}S{$aG&$)oY-)TBr;88_#O9h(doTPTAj-= zYc1Pq25T43#W@!bu*PwRnA79UN=7ke1?+c*zVCH>KXp|4=9~|EUbp>{Mtgy3N%H~! zEyK58j~0lP*bxGaDt57MzHWFYwZK=Ht+FilBCfpc5_A9ChL5V88p>%O9Z$S6G}H@d z?CFs2@meZv@f7YEX9|oQ@!#yrg39n}hzXDQwba)6_?X}4*H??nO&aMVFJD-q!wDXp zhQ8}CI$x?(ilRHKE52JkG>YyCO?WlWxAgnO<*`3k6R@r|m`~>AvzL43!9yjBdUX=J z!;5lo+p`tUiVk?^9VQ^~i( z2p*04`Vp%5QMIdKT5Tiyj#f6$`)NFMK4>npgWj-V`j4xOngmbHY954v0*_aFAYz}cgH zxXSY$Lq?#YDbFdzkMXe`0jSOd2iDcr${LSr>HDk{3C1sPB^gMyE_lD()7u;v z_%v5zJ0~tI?M?6Uow?or?KRH3xj_JrIlm=3&uGhqE6+O!&q0PG^LJ}rzuT32bR{P6 zqUiOD&+QhL{J+gy^)8VT_q7nRDel{q`)hD?;>G)luQ|hd;~(hST!cvMLasG4jRu}? zfMF*t?t2|6VhPsy-F=2zB({)@(L!#a(|?E`3-j=u*(A3e{aCT9uR6Y53LnbpLU~A7dL<5=`c&5QmB)OmPsDepq!Y6h zN_mmG3d$p2r%k)kZ!?+Pt>qnQJfk6UAUZ_Z?uSuW>;*Gv*1_4u7EhUU@O41XD8~_3 z(IE312mI@IxlQJd(1?2n&mxdP}$|FkdXapA~Og2O8!)mqF?Ms#rxM)RqG{QT;cUNbw$3=%46b7>tW|;;ent4 zQu*Sxh$8VCzxKqPlXq)`3_1>m1Ru&&>2X-ux^S*MY`@|{r;OMQwRpek7>Sg4OXTM**8~xz%5mHlExP^dhXu%7VupG#RI@USCvd(6v03RWp>4 zSFnq)Wl)Pn^-Q@ymguwnuJ4=jrmP=#T$kzNj>6zi7G%df#E&h?X0km4v=iL8?`hac z6GF23?&jDi8RFtp=1NfPzsew7s9~z8_V#w(`7Xll*R|CxwJ? zXit)pflR0I&-5FjrKsOe6867oZmT*~kAB_!i#@jd+6Rw9-SqTlpTC?i?itztW-9h7 zcy_i=!~IRDZ!{nHIZ*h^EFm>S&hdU~`KJE;_0KQs*p2y0oSAl#w79x3#pjPwFU=;7 zdIO<4vjM)xtU{XIEShcJux4#4elmJ2>ZJ1TGaqlx3!OPvV)fv|i8`waKkfb)Mnb;y zTq%2w>&5bT7x6xqN!7Y>*KjxY?mUqnKiZDJFMnb`=@``BYZSyv*!Hu_ydAYNf;L_u zkDqk1lvxj&M@1cM&=_85q+~+rhT40mN~U$#FrZM&JSddj8Vldg!%JY`-N%58lJFdh z&lct-vkLsXIf+5So`%v?OTA(kLBfzp>e>=MZ7UCfxb^p%I(~3F z4}r-#lpd}?8Q)-!jK<2Kg8~MFXK~;n=r}w@*vjB`NvIB=-7-k&)`U-P#fY#v=p}{W zCoFn3Qh4vBFd_sY|1bnq2E(K=5`^jfofPzsG)9OZd{78Us1BZy!SLhtGvx{O5g?g? z$3+VfDx)(P$rXhr@DQ#f9Hoef%VPK-x(Fd7Ih7)KoxCJZ$W2Y4EGfuA1sy)^N3IXg zl*v!f&%8&G7t9tVIAlLTu8`Up!5(=G7vXr03%LpKz4H;Y^ZF=iFBPDQ_g$+;E+s)u z5rBbai{MoI4F>3;0|RK+=#aMvLcr0oCqd+HKKc2Bl3Ex>uoeq7 zmb;Rj3E2g3BnxP$gkd9u*PBy#@EV@f%uGPH{9yh|V*nMEp*!8x4N^k$gQ3v7%8;Bz ze*`5IUc-;Q<|b?y30hNQz+ZXCM|k?~I?^L@Z6H<^y3;2U>1)L?fn}=DCaU;WL>-#2 zuz_%EL6w!NkR<>RAga*;7RX~;)lYQ8Vo=02Vffh=Ayz zfFsC>4Dlxqu(*~}kZ2(SxUF3?fC`!z4&pZ{z-p~)44@|#5Fut`fz@iE_VN+WXaIfG zrC!y-2or0KfJ4-BPysx|1Pef%nwhVSVJCjJ2WHu+>KE9A;Uuc>1>RCURZ!O-;3oz{ z|4=lcrVA7MgMky&H+gO|RB}lK;6U}XpeMr!s>A`zM8`P5nF1Wwfm*bj40x;&SwSXU zD7x$n;7Tp2nhllhnGO72D~5&3KEgjBVqG)KE&__wVJigyClPxMsG%f4wjoO~)I8H- zplMBu0gTs&vN~1(oD?Q}_y*po0YoSr83owD0|rn>#A*S~)lbMMzzTjcz;J-c4}gxp zL{@OWA!Y-p-VKNm>l*-WYWB~E02@)N8E~dv^oDW~yV`(I$|96ojF{C4SW}Zcj4>OC zkft2<;-E2<99rZhHuVC`)QHO#=zb(#0OZd9r^qf z!Tt)MV5|qikkeQMlUWrL&cNSIvG`aa2N!BG<669J4k2U!h({=1RrO9nRoJvOF( zuKyk$Q-|)*MKtlyQ8GEDETv2oQjMb}49kIBLNqBakOA0ifSI(QjvW#O`woypm?qL} zCmDn+2$)F=dN|SHpDD^CZUkf#p$WD0fKeR=^6lYws0yxYLz6dI8FDHhizrQOvp@Mx zVABGo)1p8S8HN3e3U&8jqeb^Lt&9PKLUl2rP@5?2Avc~glpF?o957ytCS_0r8HMf6 zf8sQt+7SeVjSrYW3;M^ALC6FBzm3n92*VQO-$;Z=&?xVwMpx|;I73VGJ3%D^Td38x zhPbV7Yy0UnBEH;Be3cjPwVqd(xsHcH>=$@eil)4#>@^w)Te4NX@crxcj^t7iVY9YM zEC^XoJbi_V2-`SNU4|y<6fKs~WA_ z3QeU{p^!IREp{boeX%iwH694NM$kre$TP!2MjLcdr-9w{C@^ff!691M&y)iHW4=K* z4H~KctPrja*iVZn*i%$sLk`+&(gfagp}?>;|L1dV|8Z8aniYlmpov0ht^1sx-HUWj z8?@7+QOpjeD8fD-d`1hKhf`qK(Stj*X`(M4qrkAY|EHc)nO^VOA^%|v{lL>+S5MO^ zN*rwe!7ZC;WM5@cV0aJ!8);!IG}}UZQ4ciQOcOYnM+t<71F)JF4lVk-OUYxx>Q>22 zrr9bhWoXbx2crvC=+LCV-$yjC$OHkZ>C(V*O_U1YSpqDfh27c_Sn=Pf0#wqYk!t9s zNWt^PKh1T?HhOpiYHkYDT$6Rpz1xpGY&j4fK|m#a8ribf6j^u}A%AzRH<)wdXt2Tv zqePGRZ18RkO>Yd|Ljoi~37J&>sY}uv?Nz$$&A38_#JHMp`$hw$`|@m0D0smY>*2;{SOIv1+D-9 diff --git a/scripts/initializr/common/src/main/resources/kotlin-src.zip b/scripts/initializr/common/src/main/resources/kotlin-src.zip index 62c4b0d91ebf286b04879864fe10fdc228030322..32c52cdb23f951135e2fe1da62acbf084a784591 100644 GIT binary patch literal 1507 zcmWIWW@h1H00FH${}?a>O0YA?Fl6VKK{oO5@f+C#qLdW0l{rO?G#Kiw1)-7{F+x(p*J7;FK z8hSdN+VGWKQmmn57Brd z&$D`6(~Sk+^kzSu7oq>?c<3q--Rq6jhy7O{HuF?l9LS`6Bjm{fmCg?uGH(JFi^_4| z*!Cf}j)(EPRHMny3w(b!-M@UQ`th>Kou3c=vJ=kcsWz2#Iw@Aunvj)!Bk{~()tu}} ztS@CV9BsNPGY0habwKjfMye5Zh zujfmFdBPms(p#o+wQRbUkS)8zRxDguC4?nk@m`+Q4%LbT?e2pTzh0lbRbufcwjrn} zy*!|7_JZE!?muV72dZ@`?VS*l@cgjHt25DoGqx9e{=j3=%I$pr@apopDkU5C`#hNW zH0*{%vMkT$gR?BPMfGwI$2)({zVdbDK4k-m?~Hz{=O4(iy{)tF&e<^gXWP4f7V+et zdRQOwSgX!wx7zoU4^wqa7p`k&S3h~P>D}=cDYX-yCvu1J$OW_|I(?{j`hNPum90~j z_xu*eojJr&(@k=IN@^Z3q2%WgO52P~a?H3gtOPXc3NXBN1To>+mlcwIF|sah!?+oc z4Fj15H4KuKNjFd!#lSXH0}P48DxrU|1H%XFRS94haZgerH(Hs0O5v0s`i4 ti1Db|9iLU$BTyX0Cvm{i1<5MZ6oSieRyLqB8Q6eOj){R`JO0Waz?EI3P%sl-7oQk*+ijwnl@hB8VRhU|lm|KvOibsPa zb`80ei3J5x)!DsdqijNQ3BT(`3GXeYCo(K%NZwqn_vya3*Qeu2lbNm_ zoYvO=l(WK)^8o-t;;7^c{{3F#Xk1;vUc}Wch*}~nw%3U zIepQt8d=%fGd6@3Z$7w4S7%>eR?n`yAf@lieqPJ)zHNSX|77p)rqe&lcLeOuJRkM!rquo?&fjgrLWY%2AACQE1b(`}W_7pscGF|GHv(Bv z-f?-eOkM9wXDnj)cfp$X*3=IUC#9BKIGmq)ak<+eDc!e@>~EZ%uV2>gm?7leDch=Ug-E`K|t>JXUt@lNG6u4MtUC2XTkH*1KPZesGXNc@vqS!MrBil=~ zVl}s)QW1~rK>-bqdi9&ftGjj{{u{jLKzWkiU!Mc{6P%hKuT$TV;QOOx;p)T7qipV- zv(t6Ic|7yHg}pmp`uYX=hIZfiZ-r^ zeJ#MAB=a)L>*R0G*FqaJD}VjcTg$=Mde!jIqPbQ3Mdq%1up{e}V9n_U`CA*!+Olt$ z@Hst}sNQn&@Z_Vviqvij{yaLj@w`Y*rD5A+)$m+9soM7kHv9a&lyv@IYwgpL0{e&B zi%TM(rR$|{yS%XBm#B&P9@EPD1Lg;`Euy{UAKd+YuT{Ik(tkpSi+AV72U~?J4&Dif z{rqC>i_Y%&53!aXqwh%{*3Yhfeej?t%W?m`>g~!WFQ0l67E|MPdN-@$-;Ao72l3Y0COKx@1rJas5C|~5bp+AyVhFb;P(cI%AWdkc06yD51rtJ}ACL*P z4OE^XiYeSSg9<7L0NGp*WMVM@R&0Tc!Ci2Hj9~=gC5_wg8G~Gm;qw|O{2>73GA9-k Ym!ZZ6E3oKfU|<8nKA;22fl3(|08`W^mH+?% diff --git a/scripts/initializr/common/src/main/resources/skill/SKILL.md b/scripts/initializr/common/src/main/resources/skill/SKILL.md index e8941d36b9a..e3d88dbd20b 100644 --- a/scripts/initializr/common/src/main/resources/skill/SKILL.md +++ b/scripts/initializr/common/src/main/resources/skill/SKILL.md @@ -21,7 +21,7 @@ This skill teaches you how to write code for a Codename One (CN1) cross-platform `SKILL.md` (this file) is the top-level cheat sheet. Deeper reference material lives under `references/` — pull the relevant file in **only when you need it**: - `references/build-and-run.md` — Local vs cloud builds, JDK matrix, Maven goals, `codenameone_settings.properties`, running the simulator, building for iOS/Android/Web, automated (Enterprise) cloud builds in CI. -- `references/build-hints.md` — Build hints: the typed `@Ios` / `@Android` / `@Desktop` annotations that the compiler checks, and the `codename1.arg.*` properties form for everything they do not cover yet. +- `references/build-hints.md` — Curated index of `codename1.arg.*` build hints (iOS, Android, push, web). - `references/java-api-subset.md` — How to inspect the supported Java API subset, IO (`Storage`, `FileSystemStorage`), networking (`ConnectionRequest`, `Rest`), OAuth/OpenID Connect (`OidcClient`), WebSockets (cn1lib), concurrency, dates, SQLite. **Read this whenever the compliance check fails or when you reach for a `java.*` API.** - `references/api-clients.md` — The three "spec to typed client" code generators that share one architecture: REST/OpenAPI (`cn1:generate-openapi` + `@RestClient`), gRPC (`cn1:generate-grpc` + `@GrpcClient`), and GraphQL (`cn1:generate-graphql` + `@GraphQLClient`). Read this when the backend has an OpenAPI spec, a `.proto`, or a GraphQL schema and you want a generated, annotated client instead of hand-rolling calls. - `references/ui-components.md` — Form, Toolbar, Container layouts (Border/Box/Flow/Grid/Layered), common components, navigation, dialogs. diff --git a/scripts/initializr/common/src/main/resources/skill/references/android-to-cn1.md b/scripts/initializr/common/src/main/resources/skill/references/android-to-cn1.md index 2c23a546e26..73f16aef281 100644 --- a/scripts/initializr/common/src/main/resources/skill/references/android-to-cn1.md +++ b/scripts/initializr/common/src/main/resources/skill/references/android-to-cn1.md @@ -116,7 +116,7 @@ The EDT/UI-thread rule is identical in spirit to Android: never touch a componen | `Retrofit` / `OkHttp` | Not in the JDK subset. | `Rest.get/post(...).fetchAsJsonMap(...)` — see `references/java-api-subset.md`. | | `Coroutines` / `RxJava` | No coroutines runtime; no RxJava in the subset. | `Display.startThread(...)` + `Display.callSerially(...)`; chain callbacks. | | `R.string.xxx`, `R.drawable.xxx` | No resources system. | `UIManager.getInstance().localize("name", "default")` for strings (reads `messages.properties` bundles); load images by file name `Image.createImage("/foo.png")`. | -| `Permission` manifest entries | Different mechanism. | `Display.requestPermission(...)` at runtime + `@Android(xpermissions = ...)` build hint annotation (see `references/build-hints.md`). | +| `Permission` manifest entries | Different mechanism. | `Display.requestPermission(...)` at runtime + `codename1.arg.android.xpermissions` build hint (see `references/build-hints.md`). | | `Activity onCreate/onResume/onPause` | No Activity lifecycle. | Override `Lifecycle.init/start/stop` (app-level) and react to `Form.show()` (per-screen). | | `AsyncTask` | Deprecated upstream too. | `Display.startThread(...)` + `callSerially(...)`. | | `BroadcastReceiver` | No analog at the CN1 level. | For lifecycle-related events (`Lifecycle.start()` etc.) use the CN1 lifecycle. For external system events use a native interface. | diff --git a/scripts/initializr/common/src/main/resources/skill/references/build-and-run.md b/scripts/initializr/common/src/main/resources/skill/references/build-and-run.md index 6dba2b6b60e..7965ce7a0a9 100644 --- a/scripts/initializr/common/src/main/resources/skill/references/build-and-run.md +++ b/scripts/initializr/common/src/main/resources/skill/references/build-and-run.md @@ -198,27 +198,15 @@ This file lives at `common/codenameone_settings.properties`. The most useful key codename1.packageName=com.example.myapp codename1.mainName=MyAppName codename1.displayName=My App Name -codename1.kotlin=false codename1.arg.java.version=17 # Required: routes the build to the Java 17 build server +codename1.arg.ios.includePush=false +codename1.kotlin=false +codename1.arg.android.xpermissions=... +codename1.arg.ios.deployment_target=14.0 +codename1.arg.ios.teamId=ABCDEF1234 ``` -Anything prefixed `codename1.arg.` is forwarded to the build server. Note that -`java.version` stays here on purpose -- it picks the toolchain that compiles the app, -so it is resolved before any of the app's own classes exist. - -Most other build hints are better written as annotations on the main class, where the -compiler checks them: - -```java -@Ios(includePush = false, deploymentTarget = "14.0", teamId = "ABCDEF1234") -@Android(xpermissions = "...") -public class MyAppName extends Lifecycle { -} -``` - -Declaring the same hint in both places fails the build. See -[`build-hints.md`](build-hints.md) for which hints have an annotation and which are -still set in the properties file. +Anything prefixed `codename1.arg..` is forwarded to the build server. See [`build-hints.md`](build-hints.md) for the curated index of build hints. The complete reference is in the Codename One Developer Guide at . ## Layout invariants diff --git a/scripts/initializr/common/src/main/resources/skill/references/build-hints.md b/scripts/initializr/common/src/main/resources/skill/references/build-hints.md index 136d14fa16c..d5f9d31023c 100644 --- a/scripts/initializr/common/src/main/resources/skill/references/build-hints.md +++ b/scripts/initializr/common/src/main/resources/skill/references/build-hints.md @@ -1,159 +1,14 @@ # Build Hints Reference -Build hints control native platform behaviour that cannot be expressed in Java or CSS: permissions, frameworks, plist entries, signing, SDK versions. There are two ways to set one, and you should prefer the first. +Build hints are key/value pairs in `common/codenameone_settings.properties` that are forwarded to the Codename One build server. Every key starts with `codename1.arg.` (the build server strips that prefix). They control native platform behaviour that cannot be expressed in Java/CSS: permissions, frameworks, splash screens, signing, platform SDK versions, etc. -## 1. Annotations on the main class (preferred) +This file is a curated index of the most commonly needed hints. The complete authoritative reference is in the Codename One Developer Guide: -Most commonly used hints have a typed annotation in `com.codename1.annotations.buildhints`. Put them on the class named by `codename1.mainName`: +- — full guide +- — editing build hints from the simulator's *Build Hints* menu +- — variable substitution syntax for hints -```java -import com.codename1.annotations.buildhints.*; - -@Ios(newStorageLocation = true, deploymentTarget = "14.0", pods = {"Firebase/Core"}) -@Android(minSdkVersion = 24, useAndroidX = true) -@Desktop(titleBar = DesktopTitleBar.NATIVE) -public class MyApplication extends Lifecycle { -} -``` - -**Use this form whenever the hint appears in the generated table below.** The compiler checks it: a misspelled name is an unknown symbol, a wrong value type is a type error, and a value outside a hint's supported set is an unknown enum constant. An attribute you do not set is not written at all, so the build's own default still applies. - -## 2. `common/codenameone_settings.properties` (everything else) - -Hints with no annotation, and open-ended families such as `android.permission.`, are set as `codename1.arg.=` lines. This form still works exactly as it always has and nothing validates it — a misspelled key is accepted, never read, and silently does nothing. - -**Setting the same hint in both places fails the build.** Move a hint rather than copying it. - -## Annotated hints - -Every attribute below is generated from the build hint catalog, so it is always in step with what the builders actually read. - - - - -### `@IosPrivacy` - -| Attribute | Type | Build hint | -| --- | --- | --- | -| `calendarsFullAccessUsageDescription` | `String` | `codename1.arg.ios.NSCalendarsFullAccessUsageDescription` | -| `calendarsUsageDescription` | `String` | `codename1.arg.ios.NSCalendarsUsageDescription` | -| `calendarsWriteOnlyAccessUsageDescription` | `String` | `codename1.arg.ios.NSCalendarsWriteOnlyAccessUsageDescription` | -| `cameraUsageDescription` | `String` | `codename1.arg.ios.NSCameraUsageDescription` | -| `healthShareUsageDescription` | `String` | `codename1.arg.ios.NSHealthShareUsageDescription` | -| `healthUpdateUsageDescription` | `String` | `codename1.arg.ios.NSHealthUpdateUsageDescription` | -| `localNetworkUsageDescription` | `String` | `codename1.arg.ios.NSLocalNetworkUsageDescription` | -| `locationAlwaysAndWhenInUseUsageDescription` | `String` | `codename1.arg.ios.NSLocationAlwaysAndWhenInUseUsageDescription` | -| `locationAlwaysUsageDescription` | `String` | `codename1.arg.ios.NSLocationAlwaysUsageDescription` | -| `locationWhenInUseUsageDescription` | `String` | `codename1.arg.ios.NSLocationWhenInUseUsageDescription` | -| `microphoneUsageDescription` | `String` | `codename1.arg.ios.NSMicrophoneUsageDescription` | -| `remindersFullAccessUsageDescription` | `String` | `codename1.arg.ios.NSRemindersFullAccessUsageDescription` | -| `remindersUsageDescription` | `String` | `codename1.arg.ios.NSRemindersUsageDescription` | - -### `@Ios` - -| Attribute | Type | Build hint | -| --- | --- | --- | -| `addLibs` | `String[]` | `codename1.arg.ios.add_libs` | -| `applicationQueriesSchemes` | `String[]` | `codename1.arg.ios.applicationQueriesSchemes` | -| `beforeFinishLaunching` | `String` | `codename1.arg.ios.beforeFinishLaunching` | -| `bundleVersion` | `String` | `codename1.arg.ios.bundleVersion` | -| `dependencyManager` | `IosDependencyManager.AUTO\|COCOAPODS\|SPM\|BOTH\|NONE` | `codename1.arg.ios.dependencyManager` | -| `deploymentTarget` | `String` | `codename1.arg.ios.deployment_target` | -| `glAppDelegateHeader` | `String` | `codename1.arg.ios.glAppDelegateHeader` | -| `includePush` | `boolean` | `codename1.arg.ios.includePush` | -| `interfaceOrientation` | `String` | `codename1.arg.ios.interface_orientation` | -| `minDeploymentTarget` | `String` | `codename1.arg.ios.minDeploymentTarget` | -| `newStorageLocation` | `boolean` | `codename1.arg.ios.newStorageLocation` | -| `objC` | `boolean` | `codename1.arg.ios.objC` | -| `plistInject` | `String` | `codename1.arg.ios.plistInject` | -| `pods` | `String[]` | `codename1.arg.ios.pods` | -| `podsPlatform` | `String` | `codename1.arg.ios.pods.platform` | -| `podsSources` | `String[]` | `codename1.arg.ios.pods.sources` | -| `prerenderedIcon` | `boolean` | `codename1.arg.ios.prerendered_icon` | -| `projectType` | `IosProjectType.IOS\|IPAD\|IPHONE` | `codename1.arg.ios.project_type` | -| `spmPackages` | `String[]` | `codename1.arg.ios.spm.packages` | -| `teamId` | `String` | `codename1.arg.ios.teamId` | -| `themeMode` | `IosThemeMode.AUTO\|MODERN\|IOS7\|LEGACY` | `codename1.arg.ios.themeMode` | -| `uiscene` | `boolean` | `codename1.arg.ios.uiscene` | -| `urlScheme` | `String` | `codename1.arg.ios.urlScheme` | - -### `@Android` - -| Attribute | Type | Build hint | -| --- | --- | --- | -| `activityLaunchMode` | `String` | `codename1.arg.android.activity.launchMode` | -| `appBundle` | `boolean` | `codename1.arg.android.appBundle` | -| `buildToolsVersion` | `String` | `codename1.arg.android.buildToolsVersion` | -| `captureRecord` | `String` | `codename1.arg.android.captureRecord` | -| `debug` | `boolean` | `codename1.arg.android.debug` | -| `disableR8` | `boolean` | `codename1.arg.android.disableR8` | -| `enableProguard` | `boolean` | `codename1.arg.android.enableProguard` | -| `gradleDep` | `String[]` | `codename1.arg.android.gradleDep` | -| `hideStatusBar` | `boolean` | `codename1.arg.android.hideStatusBar` | -| `installLocation` | `InstallLocation.AUTO\|INTERNAL_ONLY\|PREFER_EXTERNAL` | `codename1.arg.android.installLocation` | -| `licenseKey` | `String` | `codename1.arg.android.licenseKey` | -| `minSdkVersion` | `int` | `codename1.arg.android.min_sdk_version` | -| `multidex` | `boolean` | `codename1.arg.android.multidex` | -| `newFirebaseMessaging` | `boolean` | `codename1.arg.android.newFirebaseMessaging` | -| `proguardKeep` | `String[]` | `codename1.arg.android.proguardKeep` | -| `release` | `boolean` | `codename1.arg.android.release` | -| `repositories` | `String[]` | `codename1.arg.android.repositories` | -| `targetSDKVersion` | `int` | `codename1.arg.android.targetSDKVersion` | -| `themeMode` | `AndroidThemeMode.AUTO\|MODERN\|HOLOLIGHT\|LEGACY` | `codename1.arg.and.themeMode` | -| `topDependency` | `String[]` | `codename1.arg.android.topDependency` | -| `useAndroidX` | `boolean` | `codename1.arg.android.useAndroidX` | -| `xapplication` | `String` | `codename1.arg.android.xapplication` | -| `xgradle` | `String[]` | `codename1.arg.android.xgradle` | -| `xpermissions` | `String` | `codename1.arg.android.xpermissions` | - -### `@Desktop` - -| Attribute | Type | Build hint | -| --- | --- | --- | -| `adaptToRetina` | `boolean` | `codename1.arg.desktop.adaptToRetina` | -| `fullscreen` | `boolean` | `codename1.arg.desktop.fullscreen` | -| `height` | `int` | `codename1.arg.desktop.height` | -| `interactiveScrollbars` | `boolean` | `codename1.arg.desktop.interactiveScrollbars` | -| `resizable` | `boolean` | `codename1.arg.desktop.resizable` | -| `titleBar` | `DesktopTitleBar.NATIVE\|CUSTOM\|TOOLBAR` | `codename1.arg.desktop.titleBar` | -| `width` | `int` | `codename1.arg.desktop.width` | - -### `@OnDeviceDebug` - -| Attribute | Type | Build hint | -| --- | --- | --- | -| `android` | `boolean` | `codename1.arg.android.onDeviceDebug` | -| `ios` | `boolean` | `codename1.arg.ios.onDeviceDebug` | -| `iosProxyHost` | `String` | `codename1.arg.ios.onDeviceDebug.proxyHost` | -| `iosProxyPort` | `int` | `codename1.arg.ios.onDeviceDebug.proxyPort` | -| `iosWaitForAttach` | `boolean` | `codename1.arg.ios.onDeviceDebug.waitForAttach` | - -### `@Build` - -| Attribute | Type | Build hint | -| --- | --- | --- | -| `facebookAppId` | `String` | `codename1.arg.facebook.appId` | -| `gcmSenderId` | `String` | `codename1.arg.gcm.sender_id` | -| `nativeTheme` | `NativeThemeMode.MODERN\|LEGACY\|CUSTOM` | `codename1.arg.nativeTheme` | -| `noExtraResources` | `boolean` | `codename1.arg.noExtraResources` | - -### `@Hardening` - -| Attribute | Type | Build hint | -| --- | --- | --- | -| `allowUnhardenedLocalBuild` | `boolean` | `codename1.arg.harden.allowUnhardenedLocalBuild` | -| `controlFlow` | `HardenControlFlow.OFF\|ON` | `codename1.arg.harden.controlFlow` | -| `keep` | `String` | `codename1.arg.harden.keep` | -| `level` | `HardenLevel.OFF\|STANDARD\|AGGRESSIVE\|PARANOID` | `codename1.arg.harden.level` | -| `rename` | `boolean` | `codename1.arg.harden.rename` | -| `strings` | `HardenStrings.OFF\|CONSTANTS\|ALL` | `codename1.arg.harden.strings` | - - - -## Hints with no annotation yet - -These are set in `common/codenameone_settings.properties`. +When in doubt, search the developer guide for the exact key name — there are hundreds of hints and only the ones you actually need are listed here. ## Universal @@ -166,20 +21,48 @@ These are set in `common/codenameone_settings.properties`. | Hint | Effect | | --- | --- | +| `codename1.arg.ios.deployment_target=14.0` | Minimum iOS version. Set to the lowest iOS you actually support. | +| `codename1.arg.ios.teamId=ABCDEF1234` | Apple Developer Team ID; used by `ios-source` Xcode projects for code signing. | +| `codename1.arg.ios.includePush=true` | Include APNs entitlements + frameworks for push. | +| `codename1.arg.ios.add_libs=libsqlite3.0.dylib;libxml2.dylib` | Link extra system libraries. | +| `codename1.arg.ios.pods=Firebase/Core,Firebase/Analytics` | CocoaPods to include. | +| `codename1.arg.ios.pods.platform=14.0` | Pod platform target (must be >= deployment_target). | +| `codename1.arg.ios.pods.sources=https://github.com/CocoaPods/Specs.git` | Custom Pod source repos. | +| `codename1.arg.ios.objC=true` | Allow the iOS port to use Objective-C runtime features the strict mode would block. | +| `codename1.arg.ios.NSCameraUsageDescription=...` | Camera privacy description in `Info.plist`. See *iOS privacy strings* below for the pattern. | +| `codename1.arg.ios.NSLocationWhenInUseUsageDescription=...` | Location (in-use) privacy description. | | `codename1.arg.ios.NSPhotoLibraryUsageDescription=...` | Photo library privacy description. | +| `codename1.arg.ios.NSMicrophoneUsageDescription=...` | Microphone privacy description. | +| `codename1.arg.ios.plistInject=...raw XML...` | Inject raw `……` snippets into `Info.plist` for keys that don't have a dedicated `ios.NS*` hint above. | +| `codename1.arg.ios.glAppDelegateHeader=#import "MyHeader.h"` | Prepend custom imports to the generated AppDelegate. | | `codename1.arg.ios.statusbar_hidden=true` | Hide the iOS status bar. | +| `codename1.arg.ios.beforeFinishLaunching=...` | Native code inserted before iOS's `application:didFinishLaunchingWithOptions:` returns. | +| `codename1.arg.ios.newStorageLocation=true` | Use modern iOS storage paths (recommended for new apps). | | `codename1.arg.ios.wallet.extension=true` | Generate an Apple Wallet issuer-provisioning extension (iOS 14+). See *Apple Wallet issuer provisioning* below. | ## Android | Hint | Effect | | --- | --- | +| `codename1.arg.android.targetSDKVersion=34` | Target SDK in the manifest (drives Play Store acceptance). | +| `codename1.arg.android.min_sdk_version=24` | Minimum Android API level. | +| `codename1.arg.android.buildToolsVersion=34.0.0` | Android build-tools version. Also selects the compile SDK — there is no separate compile-SDK hint. | +| `codename1.arg.android.xpermissions=` | Inject extra `` lines into the manifest. | +| `codename1.arg.android.xapplication=` | Inject XML inside the manifest's `` element. | +| `codename1.arg.android.activity.launchMode=singleTask` | Launch mode for the main activity. | | `codename1.arg.android.statusbar_hidden=true` | Hide the Android status bar. | +| `codename1.arg.android.debug=false` | Whether to build a debug APK in addition to release. | +| `codename1.arg.android.licenseKey=...` | Google Play licensing key. | +| `codename1.arg.android.release=true` | Treat the build as a release (R8/ProGuard on, etc.). | +| `codename1.arg.android.proguardKeep=...` | Extra ProGuard `-keep` rules. | +| `codename1.arg.android.gradleDep=implementation 'com.example:lib:1.0'` | Inject Gradle dependencies. | ## Push notifications | Hint | Effect | | --- | --- | +| `gcm.sender_id=1234567890` | Firebase/GCM sender ID for Android push. | +| `codename1.arg.ios.includePush=true` | Pair with the FCM/APNs setup on the iOS side. | ## iOS privacy strings (`Info.plist`) diff --git a/scripts/initializr/common/src/main/resources/skill/references/native-interfaces.md b/scripts/initializr/common/src/main/resources/skill/references/native-interfaces.md index d06bbc2d55a..75d16576b02 100644 --- a/scripts/initializr/common/src/main/resources/skill/references/native-interfaces.md +++ b/scripts/initializr/common/src/main/resources/skill/references/native-interfaces.md @@ -109,21 +109,18 @@ This step matters because every platform has a different stub layout, naming con The CN1 iOS port runs **without ARC** for these `.m` files (`CLANG_ENABLE_OBJC_ARC=NO`). Don't rely on autorelease-pool magic; retain manually or use static singletons for objects whose lifetime needs to outlive a method call. (This is also true for native code authored in `Ports/iOSPort/nativeSources/`.) -iOS Info.plist privacy strings have **dedicated, compiler-checked names**. Set them with `@IosPrivacy` on the main class rather than hand-writing plist XML: +iOS Info.plist privacy strings have **dedicated build hint names** — set them directly, don't fall back to `ios.plistInject`. The pattern is `ios.=`: -```java -@IosPrivacy( - cameraUsageDescription = "Scan QR codes to pair the device.", - locationWhenInUseUsageDescription = "Find nearby branches near your location.", - microphoneUsageDescription = "Record voice notes." -) -public class MyAppName extends Lifecycle { -} +```properties +codename1.arg.ios.NSCameraUsageDescription=Scan QR codes to pair the device. +codename1.arg.ios.NSLocationWhenInUseUsageDescription=Find nearby branches near your location. +codename1.arg.ios.NSPhotoLibraryUsageDescription=Attach photos to support tickets. +codename1.arg.ios.NSMicrophoneUsageDescription=Record voice notes. ``` -App Store builds reject location, camera, microphone, photo, contacts, etc. without the appropriate descriptions. Use `@Ios(plistInject = "...")` only for raw XML keys that have no dedicated attribute. +App Store builds reject location, camera, microphone, photo, contacts, etc. without the appropriate descriptions. Use `ios.plistInject` only for raw XML keys that don't have a dedicated hint. -If you need a CocoaPod dependency, add it with `@Ios(pods = {"PodName"})`. +If you need a CocoaPod dependency, add `codename1.arg.ios.pods=PodName,...` to `codenameone_settings.properties`. ### Android (Java) @@ -150,15 +147,13 @@ public class GpsBridgeImpl { } ``` -Permissions in the Android manifest are injected with `@Android(xpermissions = ...)`: +Permissions in the Android manifest are injected via `codename1.arg.android.xpermissions`. For example: -```java -@Android(xpermissions = "") -public class MyAppName extends Lifecycle { -} +```properties +codename1.arg.android.xpermissions= ``` -Extra Gradle dependencies go in `@Android(gradleDep = {"implementation 'com.example:lib:1.0'"})`. See `references/build-hints.md`. +Extra Gradle dependencies go in `codename1.arg.android.gradleDep`. See `references/build-hints.md`. ### JavaScript (TeaVM-friendly JS) @@ -304,6 +299,6 @@ navigator.geolocation.watchPosition(function(pos) { - **Method signature mismatch between the interface and the stub** — happens after you edit the Java interface but forget to regenerate. Re-run `mvn cn1:generate-native-interfaces -Dcn1.generateNativeInterfaces.overwrite=true` and re-apply your platform code. - **Returning Java objects** — not supported by the bridge marshaler. Return primitives, `String`, `byte[]`, or `PeerComponent` only. - **`PeerComponent` on iOS without ARC** — peer-component implementations can dangle if you treat the bridge like an ARC-managed Swift method. Retain natively, or wrap returned views in a static holder. -- **Permissions / Info.plist** — the build server happily accepts a native interface that calls a privacy-protected API, but the App Store / Play Store reject it. Set `@IosPrivacy(...)` for the plist strings and `@Android(xpermissions = ...)` for the manifest (see `references/build-hints.md`). +- **Permissions / Info.plist** — the build server happily accepts a native interface that calls a privacy-protected API, but the App Store / Play Store reject it. Set `codename1.arg.ios.plistInject` and `codename1.arg.android.xpermissions` (see `references/build-hints.md`). - **Forgetting `isSupported()` return** — defaults to `false`, so the Java side thinks the bridge isn't available. Always override. - **`NativeLookup.create()` returns null in the simulator only** — usually means the `javase/` impl class is missing or in the wrong package. diff --git a/scripts/initializr/common/src/main/resources/tweet-src.zip b/scripts/initializr/common/src/main/resources/tweet-src.zip index 431c10e5a9a8da29900812fcc29903d5d2366bcc..add354048e9050391925ac291ca7400f911061c2 100644 GIT binary patch delta 5747 zcma)A2{@E%6#i%ViLobJV`7k^ER8#KE2-P!B3Y)SlqNGW)~p#zQ;H&W)2QJVT}unf za*0+Vp>A1IRF))_BBZqH{{Q?lGVaWDd3bo9^PcxT=R4my=bNF98MXa0*s?ecJrKYH z-qbLv@j8kWfEoHbi2?tFhT{Mf_B{#!u*v`cumf=#bEWu}9sz!cHBqtJLzuNJ4o~8F zg>C8KRKFd*bg>K$wiqm@$OBYE;W^rLP!0bRIe4Dk>>WV?VGJ5QC|JCtLL48#evX^< z!@I}3{{&l%l_5(a?sXAEQE|FY=Q&*}-r?2hN6>Vn2@y3ZNmRP>=TMbR|#xgU@ zFw%0D#>y0YDExa>&{33Cgi15-B9qR@aW;9NWdq;9uI`m5S-FNyP9j%wS*eZOvaLjJMZ;YC4d6l2ro!Tz(~8V3!u-xFS` z9ne2RUfjf}t4ufYQrnVjfB8J`*2$C5{-RV~`&)OFbGS(pp9<3Mm^{b+BG zmTmQ$RSzv6OV=AcD{#Onc+s!M7;HW}l9|%{W+2|mwsN60-JINYPkm%oxAYL_Z=ZC} z0~!_bM~IL1+@Yn%G>Q_emSGa9$3BHvqkj9O!GbtIx3!!7 zG$!gV8j%{}n(n2U+m+Y)DXQF&EKw-c>-{OW=ud5XU{>yELgGH%2()e@ZH}@+@gcP& zYW1at7*nZ6Es~bAsoCS^3x|~BleIsx>(3o>YjskSy?l9##kzzLm2*$>+ojUYu;s+q z4|)x!l~|QUJ)1imbW|MdOI6XALw~)uXHy>gpZn)E_hK3A-fXCeFc~#?tx@K+#_^A^ zvwh^q3mYT1?(4PAd89?9Cv%cqpPM;%!?A;D&+V!odlUOUQU{Kl z&Q5!~S!Sz!SjRmB%BdxX)53RFp3HJ;Z`YBGPIX>=-hmZd?%~_q{~)cxo@_HuPk!%b zkHR}kIp6gk7#wIwD~Mrh?*N zhAk>*ef(|8Zw4-&E;LJO=f1n@FKE*)wQ^`4Dqf22M(w?&GuHKzQ!(4pHPB^u^6+l; z7Y2iKH)cI$J=xi@EUVS0c$f3eM+LV6G?WT0;*G8QnMCQ3PZU~yu=x&_rFrB-zZcX-M%df6w>G?s zZjP$DVRp=J;9`cI&OmXXRUz$r(o1PJzIIx|a>Gr=j{}ojimtcSNX%URx^k)FoI|PZ zdecAZp?xvL{Q0)%ZB<_>?G?w=eOJuOCI%S&zFXG!Igq37XIffmqMZF{bi-JFU}=EO zT$*HZ=9#;f&ZMwhqhfLr4hEiodNWh^rM1Kt#&JoX*s6T3(hYhw>uc*P&Uwb`sorIs z>Ka=%ljE{a!g9T|@2cy!Zl|{fT=CC~Y+>c#dR4-$HD3B@xyzS+lls#4;6hi~Ys`yI zzp^X(E}EgWp=tGhbzBQ$slD8l^;3yE{Gl)CKj8&zT6Yq3Ke;?o9-9hXO z$-Hxi%r^IvyythNXWYNx(ym(;T_5Ua{&~^z`0CN1zW3}qloRV4YiBfOM_Rl~FClEN zPF|Kwb6%X0qPf2P6l+dPt>c=M&Jbou9Fr}#uscDyDLf{JG{0pu+DztlqT|Tdq~h+R zuO+#98iB)wx^qYR`xfo5vK@D;xlOuy+@9@qB#gM2YCS(SftXs7S`|T+*=1O0aO{0c z%PReKJ;c7&IJ?xKt@xcqhtWU1~1)>O4QADnj}ap=wC5Si`Yt~<5XKMO6-wH|JhE@9@~ ztg^zOuby6JrT=O9oZ7|_$F;uIjTi6CYSs1p^uDaXgpU>-<;Df{4{*yvtf@;AoS@&|9m+`%cCLJRfhM z<|ifwq_Qeg#?pe7R@3ZCYI4Y=tLut}ADeGNhjfnXmgf`%c2%=}_s>4(_>d7aUuVua z!aaf{?rT(aFPKvFqB3Yxi%M&;E!wRT74L4CjEnVj|HmnAt)jl{m`7(qjkl^H+t~Iy znq4`YKZo^#=|N!(5Bg6A_xA|^+f0Ab=-eh`a69N}h z=sS55#4JCyasuW*+koJ02Hu;d0Xt)j*US8&d$SGt532?Ms?cm!@Z#?`q85u2Mx)RQ z5GaFHT{tnmg)CYyjWpyK0RBvIbmRWP`-O*SAUJP(C^?nPsE2;0Zgo$M;lqIKjx#`6 z@w?6(lj0w?I6^RuD-8DB_g~M&5~fZWh`A2p_M&hJ9266!fiZ>DK4pLl5K|F8%Q9rJ z%2}MQP?Qql*@)ohD=s@_#4ywsc<+J&)ZyIl2Ic;be;gB~fH6bTr^6xmfJ*-dRZ)TF zsnX%>_Te+ZK?}(aFA`M`%mk*>2b2-d{mj$eEo5 zSvL9dk3d9SmVGY3*7AJna3IanKNB%rgdLgyK&p8~CQ6A?3HHfEkWe0Fe&%1x4Qz(D zW&ROQ07OK<(WQd?!h{c3flnaH{tFd6#16)(A^n0L91t4xvzC=K2X6-TmI+%L-7mnC zPNx}#^XgRuSCJb-niIGk)G!7Cs8evi6o7$c@E^Pv8i>5mrrcxBkOzn-NeO_K@CF}gX(JQC?YVBT7ul<00}5Af;jmp zCqnR2+5{GQn*!N;m9Mkx;mZxf=^b$BYS!xe+@!5f8WzW%8=6dH@*;MGE0ZXl(2MZuK1 zK_A^gDK#N*6Ds6Xkz(K!6kz$)fShc@8BU`wNJ36kNbya+VsH~4|ByIvAA%mm0DzG| znxCKJ$%mH`aq`{$rX*TB??>RgYak>7&b6sH8)pzn7`W7P1U!sxw$hlEzr38awd zIpI^0uC6>Jyt(i>g(2a-Z6?jj5Yir;HiDCO67ER}LzZs?36#mDe_Q}3xXTD{#}2k2 U^g$#5%!a;u0SSs*VXzG=c#ck9KF&@~j!HpZo&}$+P;Tqu5aMfK zFn7DNcFOc-32{C&$Y;Gd_;@MDiVF)ae|HM9^YZm{0_Tw;Fc@71EehEnH?p6B56-A{ z^k6sv&Vtylg>d1#QMkq$)|?#O7R^TG08LkvL|zv<7QsQTV+naRSUn!j>lQ)DJUhVx zq>zmLhEvILrzUE^G*3vuU_?%^VmB0y)^0iO)1!%JCYMJfA~*Pdc=e?p5z^&(t^P4R zs57R5^1k>mTv1hH=lU$!t;I%h%q8b7S_z-_mztfcA2W4ym(p*-j#Q?ppS!o+XjAzVveu5a5#DYe zR7K8&Mh=AB3S)ROH|P6$znY}he>RY(eKBz|C^<|x9;Kch(J#%IGW2bXeicyt!!pby zOGPGL{kQtireta`?8vT?2z6my|HZ@uInxx}-zo0TVMyeNz{G`y6X(ef3ATuz%9@^) z{6Ms&dADGRcjvbKQ*S)tb0st@_HTS`si!Kqbmnn#Quf<3$@GryZnT!{V3I_{6Pjs4 zTdWxUAo;bu+NrpKEw??+GN%H(z1%~+o+rE>rau`h87lI*TlRImyrW#Vk0K+vSKe$Q zDNemLOD+1I_?g2=%)%r=G|p1x#)GZd=@QanH^k)T?C?~j)?4k zR1gsksCjA0e>ifjg|8xk@^Ed6ak}LM-9sH-8EKZbDY11o1-pKeMXcUt}P+^Hb83hbc7MY@UzyTNNmab^<^2&L)OQKb60(5`CfdOfxQ?;;FdHan#qtR z&^c23vFK;l%d%i*x?v>0f&*oT<;#-Vg^m#u;>;Us#lf1MP4dPbQ%h_84D)C17qp)L z-RRUa$zK>_*zrBNu8^&uN93e z&yU+b3rj-AYyV89B%&zQAM)uP z4J?=(+aq@=+c6X)X^_X;nlh^w&{HXzcB!=4x24)Z#;2dI9OFbKl&-;AQ733PMyc_< ziEq@l;pXNFooW9a;>?lwFdzB3So0-c_1`~SXX|7{nX17=2~h)LY+apMNE=PjuQi;~ zrUuBkt)R?|+PPExk?{|{@dLj-2b!orEaHJn+D?RpD8fl0B1}e5N zb~R5b_#+OPC!A}qYzj0xT@^!1iV>7BkjP^?H=cN~NU{mrNwh0@6FH~*1}4;&SsQw6 zemdkMTzFwnGVZp(b!6K7Yl`BvJ^r! zt?a_DMWiV2Am&z4#p{4l*=*W}rG=5N5rG%y-S9h3pSe{s7E{ruDSSBJrFKryh`L=z zzxmi9^st;AmA=hekMPwz8EI>(!g2C@2vv|o)UELe_;PKJY%bQ*?X(iN}JjNqy zQsu@a>!2ocMx^AvvM*HR(#z9Lp?9w2t)i_Ro6YkZlEy@p zmHL|0ssirtr#m*O@9`i$RPwn~gfVoz5t&zG;^dg6R#KOK&HA0yfqvr}N0aNt`H{D+ zj_p1gd7L@&@x#Lb4B2amoY7A^b~EUFl|p~}ZUYI`}Qdh}a9%?^^nC_<96^*(D&gI2KqN{KR z7OhfC$gXqw4?oT0{gS1}Pw)Nbu80y%cL6wJg_1zZaO8z80Zo@Da1;gImO#k6MJVCr z1+|ZzBPc^~EExnoo^^8yq_Px@G7eHaf2JTAvr-*lW8|v3Kn{;63Wlkzz87!n3Sb<9)RZ1Eq~j4bdCj}S+yg08~rWp6a_ z7uX0P)~5pco^U*ekc8yHAV9^H>h{_sJlqxVNOT+?$ zZYY8Tq-og$0zY#>=xDI4Wg(IKFM$uUOagNyFGQ5$Ury7-uw^b3LJ*X|oB@UK<3Nxg z<~28kilkqFi*n4_73D7D&_R{VN>xyn>jnn-krIMJ$N?iRe`2$ZZ8!iVq5%)rRjBd? zmKhzC)WGy=@Ub`>1O>JtJ2m$D{|}wb$^{BI8D1pCE*4VVP^K%FqLRcy!TX8kma9xy zSuXPrg}|zG1J8;|rxn?kmbD**m1hR8wERM|tYx4}&K}S@X|G_g_VuyHvK*lkZ|~Q(7&R8&8f=JVHV-0P9t(thp~1clLbox4W55ovKM8L4bZ{0bo&lK)D}EinGb=jC1~Bq3q5DX!x&! z)1R=7Ic*HcUQMXUg9ysdE=W^X8MmASDyb+U;7dhucM|YEff8MjK!+_vQUfpntE{u^ eAV3a)8s7$UQxy2?1cQ;l&rvK4cG(_kP5%Wz$mbvc From 8b505657e8c9fdac4c2e71496aaa3b95e1793928 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 05:32:17 +0300 Subject: [PATCH 09/23] Annotate inside the integration test, not in the archetype The test asserted the generated project already imports the build hint annotations, which was true only while the archetype template carried them. Now that generated projects stay property-backed until a release ships the package, the test adds the annotations to the generated main class itself. It annotates only hints the template does not declare -- ios.pods, ios.teamId, desktop.width, android.installLocation -- because setting one in both places is a build error, which the last section of the test covers deliberately. It also now asserts the reverse: a hint the properties file declares must not appear in the emitted resource, so the two sources stay separate. Co-Authored-By: Claude Opus 5 (1M context) --- .../build-hint-annotations-test.sh | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/maven/integration-tests/build-hint-annotations-test.sh b/maven/integration-tests/build-hint-annotations-test.sh index 49d14ede752..b5b977b4523 100755 --- a/maven/integration-tests/build-hint-annotations-test.sh +++ b/maven/integration-tests/build-hint-annotations-test.sh @@ -31,15 +31,18 @@ chmod 755 mvnw MAIN=common/src/main/java/com/example/MyApp.java SETTINGS=common/codenameone_settings.properties -echo "--- the generated project must already use annotations ---" +# The archetype deliberately still ships its hints as properties: generated +# projects are pinned to a released Codename One whose core has no +# com.codename1.annotations.buildhints, so a template carrying them would not +# compile. The annotations move there in a follow-up. Add them here instead, and +# only for hints the template does NOT declare -- setting one in both places is +# a build error, which is covered separately at the end of this test. +echo "--- annotate the generated main class ---" +perl -0pi -e 's/^import com\.codename1\.system\.Lifecycle;/import com.codename1.annotations.buildhints.*;\nimport com.codename1.system.Lifecycle;/m' $MAIN +perl -0pi -e 's/^public class MyApp extends Lifecycle \{/\@Ios(pods = {"Alamofire", "SwiftyJSON"}, teamId = "ABCDE12345")\n\@Android(installLocation = InstallLocation.INTERNAL_ONLY)\n\@Desktop(width = 1280)\npublic class MyApp extends Lifecycle {/m' $MAIN grep -q "com.codename1.annotations.buildhints" $MAIN \ - || { echo "FAIL: the archetype's main class does not import the build hint annotations"; exit 1; } -grep -q "^codename1.arg.ios.newStorageLocation" $SETTINGS \ - && { echo "FAIL: ios.newStorageLocation should have moved to @Ios, not stayed in $SETTINGS"; exit 1; } - -echo "--- add a hint of each shape ---" -perl -0pi -e 's/\@Ios\(/\@Ios(pods = {"Alamofire", "SwiftyJSON"}, teamId = "ABCDE12345", /' $MAIN -grep -q 'pods = {"Alamofire"' $MAIN || { echo "FAIL: could not patch $MAIN"; exit 1; } + || { echo "FAIL: could not add the import to $MAIN"; exit 1; } +grep -q 'pods = {"Alamofire"' $MAIN || { echo "FAIL: could not annotate $MAIN"; head -40 $MAIN; exit 1; } echo "--- process-classes must emit the hints ---" ./mvnw -B -q -pl common process-classes @@ -53,10 +56,16 @@ check() { # rather than the constant name, and an unset attribute writes nothing at all check "codename1.arg.ios.pods=Alamofire,SwiftyJSON" check "codename1.arg.ios.teamId=ABCDE12345" -check "codename1.arg.ios.themeMode=modern" -check "codename1.arg.desktop.titleBar=native" +check "codename1.arg.desktop.width=1280" +# The enum is written as the value the builder compares against, not the Java +# constant name -- INTERNAL_ONLY would be silently unrecognized. +check "codename1.arg.android.installLocation=internalOnly" grep -q "codename1.arg.ios.objC" $EMITTED \ && { echo "FAIL: an attribute nobody set must not be written"; exit 1; } +# A hint the properties file declares must not appear here: the annotations do +# not set it, and the two sources stay separate. +grep -q "codename1.arg.desktop.titleBar" $EMITTED \ + && { echo "FAIL: $EMITTED should only carry what the annotations declare"; exit 1; } echo "--- the hints must reach the build request ---" # "Build target not supported" is thrown after the merged settings file is From b2e0e86f14bc363a424b5a7aeda0a29e2224d72e Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 07:33:44 +0300 Subject: [PATCH 10/23] Four migration and Settings defects from review Kotlin string interpolation. `quote()` escaped nothing for `$`, so migrating a Kotlin main class turned any hint value containing one into an interpolated string -- an `android.gradleDep` of `implementation 'x:y:$version'` either fails to compile as an unresolved reference or silently resolves to something else. The target language is threaded into the quoting and `\$` is emitted for Kotlin only, since Java has no such construct. Imports in a default-package source. With no package declaration and no existing import, `head.indexOf("package ")` returned -1 and the arithmetic put the import at the first newline in the file -- inside the copyright comment. The project was then left with unresolved annotations and its properties entries already deleted. The class declaration is the anchor in that case. Aliases in the Settings tool. Ownership was looked up by exact name, so with `@Android(themeMode = ...)` owning `and.themeMode`, the row for its deprecated alias `cn1.androidTheme` still offered Add -- creating the second declaration of one effective setting that the next build refuses through the alias conflict check. Both sides of the lookup are canonicalised now. Credential masking. The scraper this catalog replaced inferred SECRET from names containing password, secret or token, and the Settings field masks on that type. Classifying them as STRING rendered a stored certificate password as visible text. All five -- codename1.mac.certificatePassword, macNative.notarize.password, windows.msix.password, windows.signing.password and facebook.clientToken -- are SECRET again, with a test that holds every future credential-shaped name to it. Co-Authored-By: Claude Opus 5 (1M context) --- .../_generated-build-hints.adoc | 10 +++--- .../build/shared/BuildHintsApple.java | 2 +- .../build/shared/BuildHintsDesktop.java | 4 +-- .../build/shared/BuildHintsExternal.java | 2 +- .../build/shared/BuildHintsGeneral.java | 2 +- .../maven/MigrateBuildHintsMojo.java | 34 +++++++++++++++---- .../MigrateBuildHintsPropertyParsingTest.java | 21 ++++++++++++ .../settings/CodenameOneSettings.java | 12 +++++-- .../settings/BuildHintCatalogTest.java | 32 +++++++++++++++++ 9 files changed, 100 insertions(+), 19 deletions(-) diff --git a/docs/developer-guide/_generated-build-hints.adoc b/docs/developer-guide/_generated-build-hints.adoc index d23082316d4..1173af133f9 100644 --- a/docs/developer-guide/_generated-build-hints.adoc +++ b/docs/developer-guide/_generated-build-hints.adoc @@ -1387,7 +1387,7 @@ |Mac Native cloud builds only. Path to the `.p12` file containing the Mac signing certificate(s) — _Mac App Distribution_ (3rd Party Mac Developer Application) for App Store builds, _Developer ID Application_ for Developer ID builds, or both bundled into the same P12 when `macNative.distribution=both`. Not interchangeable with the iOS distribution certificate. Required for cloud Mac builds. |codename1.mac.certificatePassword -|string +|secret |_(none)_ |_(none)_ |Mac Native cloud builds only. Password to unlock the P12 referenced by `codename1.mac.certificate`. Required for cloud Mac builds. @@ -1417,7 +1417,7 @@ |The application ID for an app that requires native Facebook login integration, this defaults to null which means native Facebook support shouldn't be in the app |facebook.clientToken -|string +|secret |_(none)_ |_(none)_ |The client token for an app that requires native Facebook login integration, this is required if the facebook.appId is set. @@ -2941,7 +2941,7 @@ | |macNative.notarize.password -|string +|secret |_(none)_ |_(none)_ | @@ -3115,7 +3115,7 @@ | |windows.msix.password -|string +|secret |_(none)_ |_(none)_ | @@ -3163,7 +3163,7 @@ | |windows.signing.password -|string +|secret |_(none)_ |_(none)_ | diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java index d606f485d0a..b8abef16dd3 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java @@ -168,7 +168,7 @@ static void register(List h) { h.add(new Hint("macNative.notarize.password") .group(HintGroup.MAC_NATIVE) - .type(HintType.STRING) + .type(HintType.SECRET) .platform("mac") .consumedBy("MacNativeBuilder")); diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java index aee3bf9532d..b4c52de1b8e 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java @@ -256,7 +256,7 @@ static void register(List h) { h.add(new Hint("windows.msix.password") .group(HintGroup.WINDOWS) - .type(HintType.STRING) + .type(HintType.SECRET) .platform("windows") .consumedBy("WindowsNativeBuilder")); @@ -316,7 +316,7 @@ static void register(List h) { h.add(new Hint("windows.signing.password") .group(HintGroup.WINDOWS) - .type(HintType.STRING) + .type(HintType.SECRET) .platform("windows") .consumedBy("WindowsNativeBuilder")); diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsExternal.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsExternal.java index 30c02b89a6e..3cdc2f5a517 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsExternal.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsExternal.java @@ -149,7 +149,7 @@ static void register(List h) { h.add(new Hint("codename1.mac.certificatePassword") .group(HintGroup.GENERAL) - .type(HintType.STRING) + .type(HintType.SECRET) .platform("general") .external() .doc("Mac Native cloud builds only. Password to unlock the P12 referenced by " diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java index c85cf6117a0..ef61db1fecb 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java @@ -181,7 +181,7 @@ static void register(List h) { h.add(new Hint("facebook.clientToken") .group(HintGroup.GENERAL) - .type(HintType.STRING) + .type(HintType.SECRET) .platform("general") .consumedBy("AndroidGradleBuilder") .doc("The client token for an app that requires native Facebook login integration, this is " diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index e1ea5a01430..2dc4d16923a 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -336,7 +336,7 @@ String toSourceLiteral(BuildHints.Hint hint, String value, boolean kotlin) { case STRING_LIST: { String sep = hint.separator(); if (sep == null || sep.length() == 0) { - return quote(v); + return quoteFor(v, kotlin); } String[] parts = v.split(java.util.regex.Pattern.quote(sep), -1); StringBuilder sb = new StringBuilder(kotlin ? "[" : "{"); @@ -349,12 +349,12 @@ String toSourceLiteral(BuildHints.Hint hint, String value, boolean kotlin) { if (written++ > 0) { sb.append(", "); } - sb.append(quote(t)); + sb.append(quoteFor(t, kotlin)); } return sb.append(kotlin ? ']' : '}').toString(); } default: - return quote(v); + return quoteFor(v, kotlin); } } @@ -373,7 +373,16 @@ static String enumConstant(String wire) { return out.length() > 0 && Character.isDigit(out.charAt(0)) ? "V" + out : out; } - private static String quote(String s) { + /** + * Renders a value as a string literal for the target language. + * + *

Kotlin interpolates {@code $} inside a string, and hint values contain + * it: an {@code android.gradleDep} of + * {@code implementation "com.x:y:${'$'}{version}"} would either fail to + * compile as an unresolved reference or silently resolve to something else. + * Java has no such construct, so the escape is emitted only for Kotlin.

+ */ + static String quoteFor(String s, boolean kotlin) { StringBuilder sb = new StringBuilder("\""); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); @@ -383,6 +392,9 @@ private static String quote(String s) { case '\n': sb.append("\\n"); break; case '\r': sb.append("\\r"); break; case '\t': sb.append("\\t"); break; + case '$': + sb.append(kotlin ? "\\$" : "$"); + break; default: sb.append(c); } } @@ -456,9 +468,17 @@ private void insertAnnotations(File source, String annotations, String simpleNam int eol = head.indexOf('\n', lastImport + 1); head = head.substring(0, eol + 1) + importLine + "\n" + head.substring(eol + 1); } else { - int pkgEnd = head.indexOf('\n', head.indexOf("package ")); - head = head.substring(0, pkgEnd + 1) + "\n" + importLine + "\n" - + head.substring(pkgEnd + 1); + // No existing import. Anchor on the package declaration, and when the + // class is in the default package anchor on the class declaration + // instead: indexOf("package ") returns -1 there, and the old + // arithmetic then put the import at the first newline in the file, + // which is inside the copyright comment. The result compiled to + // nothing useful while the properties entries had already been + // deleted. + int pkg = head.indexOf("package "); + int anchor = pkg >= 0 ? head.indexOf('\n', pkg) + 1 : head.length(); + head = head.substring(0, anchor) + (pkg >= 0 ? "\n" : "") + + importLine + "\n" + (pkg >= 0 ? "" : "\n") + head.substring(anchor); } write(source, head + annotations + tail); } diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java index 136d6faae4f..159ebd3a080 100644 --- a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java @@ -85,6 +85,27 @@ public void commentsAndBlanksDeclareNothing() { assertNull(MigrateBuildHintsMojo.propertyKeyOf(" ")); } + /// Kotlin interpolates `$` inside a string; Java does not. A hint value + /// carrying one -- a Gradle snippet such as `${'$'}{version}` -- would either + /// fail to compile as an unresolved reference or resolve to something else. + @Test + public void dollarSignsAreEscapedOnlyForKotlin() { + assertEquals("\"implementation 'x:y:\\$version'\"", + MigrateBuildHintsMojo.quoteFor("implementation 'x:y:$version'", true)); + assertEquals("\"implementation 'x:y:$version'\"", + MigrateBuildHintsMojo.quoteFor("implementation 'x:y:$version'", false)); + } + + /// The class declaration is the only safe anchor in a default-package source: + /// there is no `package` line, and the old arithmetic put the import at the + /// first newline in the file, which is inside the copyright comment. + @Test + public void aDefaultPackageSourceStillGetsAUsableAnchor() { + String src = "/*\n * Copyright\n */\npublic class MyApp {\n}\n"; + assertEquals(src.indexOf("public class MyApp"), + MigrateBuildHintsMojo.classDeclarationIndex(src, false, "MyApp")); + } + @Test public void aValueOnlyLineHasNoSeparator() { assertEquals("bare", MigrateBuildHintsMojo.propertyKeyOf("bare")); diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java index eafe3a95b44..880a7f61bb1 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java @@ -659,7 +659,13 @@ private void animatePage() { private Component hintRow(BuildHintMetadata meta) { Container row = new Container(BoxLayout.y()); row.setUIID(uiid("SettingsRow")); - String ownedBy = annotationOwnedHints.get(meta.name()); + // Look the hint up by its canonical name: a deprecated alias configures the + // same effective setting, so cn1.androidTheme is owned whenever an + // annotation owns and.themeMode. Matching on the exact name left the alias + // row offering Add, which would create the second declaration the next + // build refuses through the alias conflict check. + String ownedBy = annotationOwnedHints.get( + com.codename1.build.shared.BuildHints.canonicalName(meta.name())); boolean active = hasBuildHint(meta.name()); String value = active ? settings.getBuildHint(meta.name()) : ""; BuildHintType effectiveType = effectiveHintType(meta, value); @@ -2107,7 +2113,9 @@ private java.util.Map loadAnnotationOwnedHints() { } int eq = t.indexOf('='); if (eq > originPrefix.length()) { - out.put(t.substring(originPrefix.length(), eq).trim(), t.substring(eq + 1).trim()); + String hint = t.substring(originPrefix.length(), eq).trim(); + out.put(com.codename1.build.shared.BuildHints.canonicalName(hint), + t.substring(eq + 1).trim()); } } } catch (Exception ex) { diff --git a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java index 55741ec3ba8..825cfd4d7dd 100644 --- a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java +++ b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java @@ -125,6 +125,38 @@ public void everyAnnotatedHintNamesItsAttribute() { assertTrue(annotated > 50, "expected the curated set, got " + annotated); } + /** + * The Settings field for a credential is masked from its type. The catalog + * that replaced the old name-matching scraper has to keep classifying these + * as SECRET, or a stored certificate password renders as visible text. + */ + @Test + public void credentialHintsStayMasked() { + BuildHintCatalog catalog = BuildHintCatalog.load(); + for (BuildHintMetadata h : catalog.all()) { + String n = h.name().toLowerCase(); + if (n.contains("password") || n.contains("secret") || n.contains("token")) { + assertEquals(BuildHintType.SECRET, h.type(), + h.name() + " holds a credential and must render masked"); + } + } + } + + /** + * A deprecated alias configures the same effective setting as its target, so + * the Build Hints UI has to treat it as annotation-owned too -- otherwise its + * row still offers Add and creates the duplicate the next build refuses. + */ + @Test + public void aliasesResolveToTheirCanonicalName() { + assertEquals("and.themeMode", + com.codename1.build.shared.BuildHints.canonicalName("cn1.androidTheme")); + assertEquals("nativeTheme", + com.codename1.build.shared.BuildHints.canonicalName("cn1.nativeTheme")); + assertEquals("ios.pods", + com.codename1.build.shared.BuildHints.canonicalName("ios.pods")); + } + @Test public void searchStillMatchesOnNameAndDescription() { BuildHintCatalog catalog = BuildHintCatalog.load(); From fd05dfa07ea8037982ec7797a404c59d9ea3177f Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 09:19:23 +0300 Subject: [PATCH 11/23] Require the process-annotations binding on the module that owns the main class The guard accepted an execution anywhere in the reactor, but ProcessAnnotationsMojo scans only the output directory of the module it is bound to. A binding on a platform or utility module therefore never sees the main class that common compiles, and the migration would still delete the working properties and leave annotations nothing ever reads -- the exact failure the guard was added to prevent, one level in. It now resolves the module whose base directory is the Codename One project directory, which is where the main class lives and where findMainClassSource looks, and requires the binding there. An execution bound to phase `none` is declared but never runs, so it no longer counts either. The refusal names that module and says explicitly that binding the goal elsewhere in the reactor does not help, since that is the mistake being made. Verified against a real project: gamebuilder passes with the binding on common, and is refused when it is moved to the javase module. Co-Authored-By: Claude Opus 5 (1M context) --- .../maven/MigrateBuildHintsMojo.java | 77 ++++++++++++++++--- .../MigrateBuildHintsPropertyParsingTest.java | 33 ++++++++ 2 files changed, 98 insertions(+), 12 deletions(-) diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index 2dc4d16923a..3d704ee6c13 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -105,10 +105,14 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException // binding deletes working properties and replaces them with annotations no // goal ever reads, so the hints disappear from the build silently. if (!processAnnotationsIsBound()) { - throw new MojoFailureException("This project does not run the cn1 process-annotations " - + "goal, so build hint annotations would never be turned back into the " - + "codename1.arg.* pairs the builders read, and migrating would silently drop " - + "them.\n\nAdd it to the common module's POM first:\n" + File owner = getCN1ProjectDir(); + throw new MojoFailureException("The module that holds the main class" + + (owner == null ? "" : " (" + owner + ")") + + " does not run the cn1 process-annotations goal, so build hint annotations " + + "would never be turned back into the codename1.arg.* pairs the builders " + + "read, and migrating would silently drop them. The goal only scans the " + + "module it is bound to, so binding it elsewhere in the reactor does not " + + "help.\n\nAdd it to that module's POM first:\n" + " \n" + " cn1-process-classes\n" + " process-classes\n" @@ -239,24 +243,73 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException * lives in the common module.

*/ private boolean processAnnotationsIsBound() { + return moduleOwningTheMainClass() != null; + } + + /** + * The reactor module that both holds the main class and runs + * {@code process-annotations} over it, or null. + * + *

Checking the reactor as a whole is not enough. {@code + * ProcessAnnotationsMojo} scans only the output directory of the module it is + * bound to, so a binding on a platform or utility module never sees the main + * class that {@code common} compiles. The migration would then delete the + * properties and leave annotations nothing ever reads.

+ * + *

The owning module is the one whose base directory is the Codename One + * project directory -- the directory holding + * {@code codenameone_settings.properties}, which is also where + * {@link #findMainClassSource} looks.

+ */ + private org.apache.maven.project.MavenProject moduleOwningTheMainClass() { + File projectDir = getCN1ProjectDir(); + if (projectDir == null) { + return null; + } java.util.List projects = reactorProjects; if (projects == null || projects.isEmpty()) { projects = java.util.Collections.singletonList(project); } for (org.apache.maven.project.MavenProject p : projects) { - java.util.List plugins = p.getBuildPlugins(); - if (plugins == null) { + if (p.getBasedir() == null || !sameDirectory(p.getBasedir(), projectDir)) { continue; } - for (org.apache.maven.model.Plugin plugin : plugins) { - if (!"codenameone-maven-plugin".equals(plugin.getArtifactId())) { + return bindsProcessAnnotations(p) ? p : null; + } + return null; + } + + private static boolean sameDirectory(File a, File b) { + try { + return a.getCanonicalFile().equals(b.getCanonicalFile()); + } catch (IOException ex) { + return a.getAbsoluteFile().equals(b.getAbsoluteFile()); + } + } + + /** + * Whether this module runs {@code process-annotations} in a real phase. + * + *

An execution bound to {@code none} is declared but never runs, which for + * this purpose is the same as not being declared at all.

+ */ + static boolean bindsProcessAnnotations(org.apache.maven.project.MavenProject p) { + java.util.List plugins = p.getBuildPlugins(); + if (plugins == null) { + return false; + } + for (org.apache.maven.model.Plugin plugin : plugins) { + if (!"codenameone-maven-plugin".equals(plugin.getArtifactId())) { + continue; + } + for (org.apache.maven.model.PluginExecution e : plugin.getExecutions()) { + if (e.getGoals() == null || !e.getGoals().contains("process-annotations")) { continue; } - for (org.apache.maven.model.PluginExecution e : plugin.getExecutions()) { - if (e.getGoals() != null && e.getGoals().contains("process-annotations")) { - return true; - } + if ("none".equalsIgnoreCase(String.valueOf(e.getPhase()))) { + continue; } + return true; } } return false; diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java index 159ebd3a080..ce1a4964cfd 100644 --- a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java @@ -22,9 +22,14 @@ */ package com.codename1.maven; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; +import org.apache.maven.project.MavenProject; import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNull; /// Covers the properties parsing in `MigrateBuildHintsMojo`. @@ -106,6 +111,34 @@ public void aDefaultPackageSourceStillGetsAUsableAnchor() { MigrateBuildHintsMojo.classDeclarationIndex(src, false, "MyApp")); } + /// process-annotations scans only the output of the module it is bound to, so + /// a binding on a platform or utility module never sees the main class that + /// the common module compiles. Accepting one would let the migration delete + /// the properties and leave annotations nothing reads. + @Test + public void onlyAnEnabledExecutionOnTheOwningModuleCounts() { + assertTrue(MigrateBuildHintsMojo.bindsProcessAnnotations( + moduleBinding("process-annotations", "process-classes"))); + assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( + moduleBinding("css", "process-classes"))); + // Declared but never run is the same as absent for this purpose. + assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( + moduleBinding("process-annotations", "none"))); + } + + private static MavenProject moduleBinding(String goal, String phase) { + PluginExecution e = new PluginExecution(); + e.setPhase(phase); + e.addGoal(goal); + Plugin plugin = new Plugin(); + plugin.setGroupId("com.codenameone"); + plugin.setArtifactId("codenameone-maven-plugin"); + plugin.addExecution(e); + MavenProject p = new MavenProject(); + p.getBuild().addPlugin(plugin); + return p; + } + @Test public void aValueOnlyLineHasNoSeparator() { assertEquals("bare", MigrateBuildHintsMojo.propertyKeyOf("bare")); From 3037e76565002641bee2a0d8e40c02c89c4e2cef Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 09:52:13 +0300 Subject: [PATCH 12/23] Require an execution that can actually see compiled classes Being declared in a real phase was still not enough. ProcessAnnotationsMojo returns immediately when `skip` is set, and again when its output directory does not exist -- which is every phase before `compile`. An execution configured `true`, or bound to `generate-sources`, therefore emits no annotation resource at all, and the migration would delete the working properties and leave nothing behind. The guard now requires the execution to be unskipped and bound at or after `compile`, taking an absent phase as the goal's own default of `process-classes`. Skip is read from both the execution and the plugin configuration. Verified end to end: gamebuilder proceeds normally, and is refused once its execution carries true. Co-Authored-By: Claude Opus 5 (1M context) --- .../maven/MigrateBuildHintsMojo.java | 50 +++++++++++++++++-- .../MigrateBuildHintsPropertyParsingTest.java | 40 +++++++++++++-- 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index 3d704ee6c13..5cccbd6c5f6 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -288,10 +288,15 @@ private static boolean sameDirectory(File a, File b) { } /** - * Whether this module runs {@code process-annotations} in a real phase. + * Whether this module runs {@code process-annotations} somewhere it can + * actually see compiled classes. * - *

An execution bound to {@code none} is declared but never runs, which for - * this purpose is the same as not being declared at all.

+ *

Being declared is not enough. {@code ProcessAnnotationsMojo} returns + * immediately when {@code skip} is set, and again when its output directory + * does not exist -- which is the case for every phase before {@code compile}. + * An execution that is skipped, or bound to {@code generate-sources}, emits + * no annotation resource at all, so migrating against it would delete the + * working properties and leave nothing behind.

*/ static boolean bindsProcessAnnotations(org.apache.maven.project.MavenProject p) { java.util.List plugins = p.getBuildPlugins(); @@ -306,7 +311,10 @@ static boolean bindsProcessAnnotations(org.apache.maven.project.MavenProject p) if (e.getGoals() == null || !e.getGoals().contains("process-annotations")) { continue; } - if ("none".equalsIgnoreCase(String.valueOf(e.getPhase()))) { + if (!phaseSeesCompiledClasses(e.getPhase())) { + continue; + } + if (isSkipped(e.getConfiguration()) || isSkipped(plugin.getConfiguration())) { continue; } return true; @@ -315,6 +323,40 @@ static boolean bindsProcessAnnotations(org.apache.maven.project.MavenProject p) return false; } + /** + * The default lifecycle from {@code compile} onward -- the phases by which + * {@code target/classes} exists. + */ + private static final java.util.List PHASES_WITH_CLASSES = + java.util.Arrays.asList("compile", "process-classes", + "generate-test-sources", "process-test-sources", + "generate-test-resources", "process-test-resources", + "test-compile", "process-test-classes", "test", + "prepare-package", "package", + "pre-integration-test", "integration-test", "post-integration-test", + "verify", "install", "deploy"); + + /** + * @param phase the execution's phase, or null to accept the goal's own + * default of {@code process-classes} + */ + private static boolean phaseSeesCompiledClasses(String phase) { + if (phase == null || phase.trim().length() == 0) { + return true; + } + return PHASES_WITH_CLASSES.contains(phase.trim().toLowerCase()); + } + + /** Reads {@code true} out of a plugin or execution configuration. */ + private static boolean isSkipped(Object configuration) { + if (!(configuration instanceof org.codehaus.plexus.util.xml.Xpp3Dom)) { + return false; + } + org.codehaus.plexus.util.xml.Xpp3Dom skip = + ((org.codehaus.plexus.util.xml.Xpp3Dom) configuration).getChild("skip"); + return skip != null && "true".equalsIgnoreCase(String.valueOf(skip.getValue()).trim()); + } + /** * Whether the codenameone-core on this project's compile classpath actually * carries the annotations. diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java index ce1a4964cfd..61db8909385 100644 --- a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java @@ -25,6 +25,7 @@ import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.xml.Xpp3Dom; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -118,18 +119,47 @@ public void aDefaultPackageSourceStillGetsAUsableAnchor() { @Test public void onlyAnEnabledExecutionOnTheOwningModuleCounts() { assertTrue(MigrateBuildHintsMojo.bindsProcessAnnotations( - moduleBinding("process-annotations", "process-classes"))); + moduleBinding("process-annotations", "process-classes", false))); + // No phase means the goal's own default, process-classes. + assertTrue(MigrateBuildHintsMojo.bindsProcessAnnotations( + moduleBinding("process-annotations", null, false))); assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( - moduleBinding("css", "process-classes"))); + moduleBinding("css", "process-classes", false))); // Declared but never run is the same as absent for this purpose. assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( - moduleBinding("process-annotations", "none"))); + moduleBinding("process-annotations", "none", false))); + } + + /// ProcessAnnotationsMojo returns immediately when skip is set, and again + /// when its output directory does not exist -- which is every phase before + /// compile. Such an execution emits no annotation resource, so migrating + /// against it would delete the properties and leave nothing behind. + @Test + public void anExecutionThatCannotSeeCompiledClassesDoesNotCount() { + assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( + moduleBinding("process-annotations", "generate-sources", false))); + assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( + moduleBinding("process-annotations", "process-resources", false))); + assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( + moduleBinding("process-annotations", "process-classes", true))); + // compile is the earliest phase where target/classes exists. + assertTrue(MigrateBuildHintsMojo.bindsProcessAnnotations( + moduleBinding("process-annotations", "compile", false))); } - private static MavenProject moduleBinding(String goal, String phase) { + private static MavenProject moduleBinding(String goal, String phase, boolean skip) { PluginExecution e = new PluginExecution(); - e.setPhase(phase); + if (phase != null) { + e.setPhase(phase); + } e.addGoal(goal); + if (skip) { + Xpp3Dom config = new Xpp3Dom("configuration"); + Xpp3Dom flag = new Xpp3Dom("skip"); + flag.setValue("true"); + config.addChild(flag); + e.setConfiguration(config); + } Plugin plugin = new Plugin(); plugin.setGroupId("com.codenameone"); plugin.setArtifactId("codenameone-maven-plugin"); From af8ff86d778f436546ec8d0f550af1a89d90f9a2 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 11:11:54 +0300 Subject: [PATCH 13/23] Stop the generated simulator schema duplicating the hand-written one The group name is part of the property key, so registering harden.level under both `hardening` and `Hardening` overwrites nothing -- it creates a second group, and BuildHintEditor renders every group it finds. The user saw duplicate controls for one setting, for all of harden.*, nativeTheme, ios.themeMode and and.themeMode. The comment claiming the hand-written entries take precedence because the setter never overwrites was simply wrong: the two never collided on a key. BuildHintSchemaDefaults now records the hints it describes as it registers them, and the generated companion skips those. Precedence is explicit rather than assumed, and it cannot drift, since the record is built from the same set() calls that do the describing. Verified by walking the registered properties: 89 hints in the editor, none appearing under more than one group, and harden.level, nativeTheme, ios.themeMode and and.themeMode all resolving to their hand-written group. Also makes the integration test fail when the merged settings file is absent. It was the only assertion that annotation hints reach the build request, and skipping it on a missing file meant a regression in goal ordering, target validation or the merge itself would have left the test green. Co-Authored-By: Claude Opus 5 (1M context) --- .../impl/javase/BuildHintCatalogDefaults.java | 173 +++++++++++++++++- .../impl/javase/BuildHintSchemaDefaults.java | 24 +++ .../build/shared/BuildHintCodeGenerator.java | 12 +- .../build-hint-annotations-test.sh | 20 +- 4 files changed, 219 insertions(+), 10 deletions(-) diff --git a/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java b/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java index 8a8014201c3..c1f57e69aef 100644 --- a/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java +++ b/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintCatalogDefaults.java @@ -29,8 +29,12 @@ * BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and re-run * scripts/gen-build-hint-annotations.sh.

* - *

Registered after {@link BuildHintSchemaDefaults}, whose hand-written - * entries take precedence because the shared setter never overwrites.

+ *

Registered after {@link BuildHintSchemaDefaults} and skipping every hint + * that class already describes. Precedence cannot be left to the setter: + * the group name is part of the property key, so registering harden.level + * under both `hardening` and `Hardening` does not overwrite anything -- it + * makes a second group, and the editor renders both, giving the user + * duplicate controls for one setting.

*/ final class BuildHintCatalogDefaults { @@ -38,263 +42,428 @@ private BuildHintCatalogDefaults() { } static void register() { + java.util.Set handWritten = BuildHintSchemaDefaults.declaredHints(); set("{{@IosPrivacy}}.label", "iOS Privacy Strings"); + if (!handWritten.contains("ios.NSCalendarsFullAccessUsageDescription")) { set("{{#IosPrivacy#ios.NSCalendarsFullAccessUsageDescription}}.label", "Calendars full access usage description"); set("{{#IosPrivacy#ios.NSCalendarsFullAccessUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSCalendarsUsageDescription")) { set("{{#IosPrivacy#ios.NSCalendarsUsageDescription}}.label", "Calendars usage description"); set("{{#IosPrivacy#ios.NSCalendarsUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSCalendarsWriteOnlyAccessUsageDescription")) { set("{{#IosPrivacy#ios.NSCalendarsWriteOnlyAccessUsageDescription}}.label", "Calendars write only access usage description"); set("{{#IosPrivacy#ios.NSCalendarsWriteOnlyAccessUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSCameraUsageDescription")) { set("{{#IosPrivacy#ios.NSCameraUsageDescription}}.label", "Camera usage description"); set("{{#IosPrivacy#ios.NSCameraUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSHealthShareUsageDescription")) { set("{{#IosPrivacy#ios.NSHealthShareUsageDescription}}.label", "Health share usage description"); set("{{#IosPrivacy#ios.NSHealthShareUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSHealthUpdateUsageDescription")) { set("{{#IosPrivacy#ios.NSHealthUpdateUsageDescription}}.label", "Health update usage description"); set("{{#IosPrivacy#ios.NSHealthUpdateUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSLocalNetworkUsageDescription")) { set("{{#IosPrivacy#ios.NSLocalNetworkUsageDescription}}.label", "Local network usage description"); set("{{#IosPrivacy#ios.NSLocalNetworkUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSLocationAlwaysAndWhenInUseUsageDescription")) { set("{{#IosPrivacy#ios.NSLocationAlwaysAndWhenInUseUsageDescription}}.label", "Location always and when in use usage description"); set("{{#IosPrivacy#ios.NSLocationAlwaysAndWhenInUseUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSLocationAlwaysUsageDescription")) { set("{{#IosPrivacy#ios.NSLocationAlwaysUsageDescription}}.label", "Location always usage description"); set("{{#IosPrivacy#ios.NSLocationAlwaysUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSLocationWhenInUseUsageDescription")) { set("{{#IosPrivacy#ios.NSLocationWhenInUseUsageDescription}}.label", "Location when in use usage description"); set("{{#IosPrivacy#ios.NSLocationWhenInUseUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSMicrophoneUsageDescription")) { set("{{#IosPrivacy#ios.NSMicrophoneUsageDescription}}.label", "Microphone usage description"); set("{{#IosPrivacy#ios.NSMicrophoneUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSRemindersFullAccessUsageDescription")) { set("{{#IosPrivacy#ios.NSRemindersFullAccessUsageDescription}}.label", "Reminders full access usage description"); set("{{#IosPrivacy#ios.NSRemindersFullAccessUsageDescription}}.type", "TextField"); + } + if (!handWritten.contains("ios.NSRemindersUsageDescription")) { set("{{#IosPrivacy#ios.NSRemindersUsageDescription}}.label", "Reminders usage description"); set("{{#IosPrivacy#ios.NSRemindersUsageDescription}}.type", "TextField"); + } set("{{@Ios}}.label", "iOS"); + if (!handWritten.contains("ios.add_libs")) { set("{{#Ios#ios.add_libs}}.label", "Add libs"); set("{{#Ios#ios.add_libs}}.type", "TextArea"); set("{{#Ios#ios.add_libs}}.description", "A semicolon separated list of libraries that should be linked to the app to build it"); + } + if (!handWritten.contains("ios.applicationQueriesSchemes")) { set("{{#Ios#ios.applicationQueriesSchemes}}.label", "Application queries schemes"); set("{{#Ios#ios.applicationQueriesSchemes}}.type", "TextArea"); set("{{#Ios#ios.applicationQueriesSchemes}}.description", "Comma separated list of url schemes that `canExecute` will respect on iOS. If the url scheme isn't mentioned here `canExecute` will return false starting with iOS 9. Notice that this collides with `ios.plistInject` when used with the `LSApplicationQueriesSchemes...` value so you should use one or the other. For example, to enable `canExecute` for a url like `myurl://xys` you can use: `myurl,myotherurl`"); + } + if (!handWritten.contains("ios.beforeFinishLaunching")) { set("{{#Ios#ios.beforeFinishLaunching}}.label", "Before finish launching"); set("{{#Ios#ios.beforeFinishLaunching}}.type", "TextArea"); set("{{#Ios#ios.beforeFinishLaunching}}.description", "Objective-C code that can be injected into the iOS app delegate at the top of the body of the didFinishLaunchingWithOptions callback method"); + } + if (!handWritten.contains("ios.bundleVersion")) { set("{{#Ios#ios.bundleVersion}}.label", "Bundle version"); set("{{#Ios#ios.bundleVersion}}.type", "TextField"); set("{{#Ios#ios.bundleVersion}}.description", "Indicates the version number of the bundle, this is useful if you want to create a minor version number change for the beta testing support"); + } + if (!handWritten.contains("ios.dependencyManager")) { set("{{#Ios#ios.dependencyManager}}.label", "Dependency manager"); set("{{#Ios#ios.dependencyManager}}.type", "Select"); set("{{#Ios#ios.dependencyManager}}.values", "auto,cocoapods,spm,both,none"); set("{{#Ios#ios.dependencyManager}}.description", "Which native dependency manager to use: auto picks one from whichever of ios.pods and ios.spm.packages is set, and cocoapods, spm or both require the matching hint to be set. An unrecognized value fails the build."); + } + if (!handWritten.contains("ios.deployment_target")) { set("{{#Ios#ios.deployment_target}}.label", "Deployment target"); set("{{#Ios#ios.deployment_target}}.type", "TextField"); set("{{#Ios#ios.deployment_target}}.description", "Minimum iOS version the build targets. Set it to the lowest iOS you actually support; a higher value excludes older devices from the App Store listing."); + } + if (!handWritten.contains("ios.glAppDelegateHeader")) { set("{{#Ios#ios.glAppDelegateHeader}}.label", "Gl app delegate header"); set("{{#Ios#ios.glAppDelegateHeader}}.type", "TextArea"); set("{{#Ios#ios.glAppDelegateHeader}}.description", "Objective-C code that can be injected into the iOS app delegate at the top of the file. For example, if you need to include headers or make special imports for other injected code"); + } + if (!handWritten.contains("ios.includePush")) { set("{{#Ios#ios.includePush}}.label", "Include push"); set("{{#Ios#ios.includePush}}.type", "Checkbox"); set("{{#Ios#ios.includePush}}.description", "true/false (defaults to false). Whether to include the push capabilities in the iOS build. Notice that the IDE plugin has an \"Include Push\" check box you *should* use under the iOS section."); + } + if (!handWritten.contains("ios.interface_orientation")) { set("{{#Ios#ios.interface_orientation}}.label", "Interface orientation"); set("{{#Ios#ios.interface_orientation}}.type", "TextField"); set("{{#Ios#ios.interface_orientation}}.description", "UIInterfaceOrientationPortrait by default. Indicates the orientation, one or more of (separated by colon :): `UIInterfaceOrientationPortrait`, `UIInterfaceOrientationPortraitUpsideDown`, `UIInterfaceOrientationLandscapeLeft`, `UIInterfaceOrientationLandscapeRight`. Notice that the IDE plugin has an \"Interface Orientation\" combo box you *should* use under the iOS section."); + } + if (!handWritten.contains("ios.minDeploymentTarget")) { set("{{#Ios#ios.minDeploymentTarget}}.label", "Min deployment target"); set("{{#Ios#ios.minDeploymentTarget}}.type", "TextField"); set("{{#Ios#ios.minDeploymentTarget}}.description", "The null and empty-string reads of this hint are presence checks; 6.0 is the substantive default (IPhoneBuilder.java:4671)."); + } + if (!handWritten.contains("ios.newStorageLocation")) { set("{{#Ios#ios.newStorageLocation}}.label", "New storage location"); set("{{#Ios#ios.newStorageLocation}}.type", "Checkbox"); set("{{#Ios#ios.newStorageLocation}}.description", "true/false defaults to false but defined on new projects as true by default. This changes the storage directory on iOS from using caches to using the documents directory which is the recommended location but might break compatibility. This is described in https://github.com/codenameone/CodenameOne/issues/1480[this issue]"); + } + if (!handWritten.contains("ios.objC")) { set("{{#Ios#ios.objC}}.label", "Obj c"); set("{{#Ios#ios.objC}}.type", "Checkbox"); set("{{#Ios#ios.objC}}.description", "Added the `-ObjC` compile flag to the project files which some native libraries require"); + } + if (!handWritten.contains("ios.plistInject")) { set("{{#Ios#ios.plistInject}}.label", "Plist inject"); set("{{#Ios#ios.plistInject}}.type", "TextArea"); set("{{#Ios#ios.plistInject}}.description", "entries to inject into the iOS plist file during build."); + } + if (!handWritten.contains("ios.pods")) { set("{{#Ios#ios.pods}}.label", "Pods"); set("{{#Ios#ios.pods}}.type", "TextArea"); set("{{#Ios#ios.pods}}.description", "A comma separated list of https://cocoapods.org/[Cocoa Pods] that should be linked to the app to build it. For example, `AFNetworking ~> 2.6, ORStackView ~> 3.0, SwiftyJSON ~> 2.3`"); + } + if (!handWritten.contains("ios.pods.platform")) { set("{{#Ios#ios.pods.platform}}.label", "Pods platform"); set("{{#Ios#ios.pods.platform}}.type", "TextField"); set("{{#Ios#ios.pods.platform}}.description", "Sets the Cocoapods 'platform' for the Cocoapods. Some Cocoapods require a minimum platform level. For example, `ios.pods.platform=7.0`."); + } + if (!handWritten.contains("ios.pods.sources")) { set("{{#Ios#ios.pods.sources}}.label", "Pods sources"); set("{{#Ios#ios.pods.sources}}.type", "TextArea"); set("{{#Ios#ios.pods.sources}}.description", "Extra CocoaPods spec repositories to search, in addition to the default trunk."); + } + if (!handWritten.contains("ios.prerendered_icon")) { set("{{#Ios#ios.prerendered_icon}}.label", "Prerendered icon"); set("{{#Ios#ios.prerendered_icon}}.type", "Checkbox"); set("{{#Ios#ios.prerendered_icon}}.description", "true/false defaults to false. The iOS build process adapts the submitted icon for iOS conventions (adding an overlay) that might not be appropriate on some icons. Setting this to true leaves the icon unchanged (only scaled)."); + } + if (!handWritten.contains("ios.project_type")) { set("{{#Ios#ios.project_type}}.label", "Project type"); set("{{#Ios#ios.project_type}}.type", "Select"); set("{{#Ios#ios.project_type}}.values", "ios,ipad,iphone"); set("{{#Ios#ios.project_type}}.description", "one of ios, ipad, iphone (defaults to ios). Indicates whether the resulting binary is targeted to the iphone only or ipad only. Notice that the IDE plugin has a \"Project Type\" combo box you *should* use under the iOS section."); + } + if (!handWritten.contains("ios.spm.packages")) { set("{{#Ios#ios.spm.packages}}.label", "Spm packages"); set("{{#Ios#ios.spm.packages}}.type", "TextArea"); set("{{#Ios#ios.spm.packages}}.description", "Swift Package Manager packages to link, one per entry, each written as identity|url|requirement."); + } + if (!handWritten.contains("ios.teamId")) { set("{{#Ios#ios.teamId}}.label", "Team id"); set("{{#Ios#ios.teamId}}.type", "TextField"); set("{{#Ios#ios.teamId}}.description", "Specifies the team ID associated with the iOS provisioning profile and certificate. Use `ios.debug.teamId` and `ios.release.teamId` to specify different team IDs for debug and release builds respectively."); + } + if (!handWritten.contains("ios.themeMode")) { set("{{#Ios#ios.themeMode}}.label", "Theme mode"); set("{{#Ios#ios.themeMode}}.type", "Select"); set("{{#Ios#ios.themeMode}}.values", "auto,modern,ios7,legacy"); set("{{#Ios#ios.themeMode}}.description", "`auto` (default), `modern`, `ios7`, `legacy`. `auto` (unset) keeps the existing iOS 7 flat theme so pre-refactor screenshot goldens and apps see no behavior change. `modern` / `liquid` opts in to the CSS-generated iOS Modern (liquid-glass) theme shipped from `native-themes/ios-modern/theme.css`. `ios7` / `flat` is the same as `auto` - pre-liquid iOS 7 flat theme; `legacy` / `iphone` loads the pre-iOS 7 iPhone theme. The `auto` -> modern flip is planned for a future release."); + } + if (!handWritten.contains("ios.uiscene")) { set("{{#Ios#ios.uiscene}}.label", "Uiscene"); set("{{#Ios#ios.uiscene}}.type", "Checkbox"); set("{{#Ios#ios.uiscene}}.description", "true/false (defaults to true). Enables iOS UIScene lifecycle support. UIScene lets iOS manage one or more app UI sessions independently, improving lifecycle handling in modern iOS versions. Apple has indicated UIScene will be required starting with iOS 27, so this is now on by default; set the flag to `false` only if you need to temporarily fall back to the legacy `UIApplicationDelegate` lifecycle."); + } + if (!handWritten.contains("ios.urlScheme")) { set("{{#Ios#ios.urlScheme}}.label", "Url scheme"); set("{{#Ios#ios.urlScheme}}.type", "TextField"); set("{{#Ios#ios.urlScheme}}.description", "Allows intercepting a URL call using the syntax `urlPrefix`"); + } set("{{@Android}}.label", "Android"); + if (!handWritten.contains("android.activity.launchMode")) { set("{{#Android#android.activity.launchMode}}.label", "Activity launch mode"); set("{{#Android#android.activity.launchMode}}.type", "TextField"); set("{{#Android#android.activity.launchMode}}.description", "Allows explicitly setting the `android:launchMode` attribute of the main activity in android. Default is \"singleTop,\" but for some applications you may need to change this behaviour. In particular, apps that are meant to open a file type will need to set this to \"singleTask.\" See https://developer.android.com/guide/topics/manifest/activity-element.html[Android docs for the activity element] for more information about the `android:launchMode` attribute."); + } + if (!handWritten.contains("android.appBundle")) { set("{{#Android#android.appBundle}}.label", "App bundle"); set("{{#Android#android.appBundle}}.type", "Checkbox"); set("{{#Android#android.appBundle}}.description", "Produces an Android App Bundle (.aab) rather than an APK. Required for new Play Store submissions."); + } + if (!handWritten.contains("android.buildToolsVersion")) { set("{{#Android#android.buildToolsVersion}}.label", "Build tools version"); set("{{#Android#android.buildToolsVersion}}.type", "TextField"); set("{{#Android#android.buildToolsVersion}}.description", "Android build-tools version. It also selects the compile SDK, so there is no separate compile-SDK hint."); + } + if (!handWritten.contains("android.captureRecord")) { set("{{#Android#android.captureRecord}}.label", "Capture record"); set("{{#Android#android.captureRecord}}.type", "TextField"); set("{{#Android#android.captureRecord}}.description", "Indicates whether the `RECORD_AUDIO` permission should be requested. Can be `enabled` or any other value to disable this option"); + } + if (!handWritten.contains("android.debug")) { set("{{#Android#android.debug}}.label", "Debug"); set("{{#Android#android.debug}}.type", "Checkbox"); set("{{#Android#android.debug}}.description", "true/false defaults to true - indicates whether to include the debug version in the build. Defaults conditionally rather than to a fixed value: when android.release is on it defaults to false, and when release is off it defaults to true, so a build that selects neither still produces something installable (AndroidGradleBuilder.java:447-451)."); + } + if (!handWritten.contains("android.disableR8")) { set("{{#Android#android.disableR8}}.label", "Disable r8"); set("{{#Android#android.disableR8}}.type", "Checkbox"); set("{{#Android#android.disableR8}}.description", "Turns off R8, falling back to the older shrinker. Note that hardening requires R8, so this conflicts with harden.level."); + } + if (!handWritten.contains("android.enableProguard")) { set("{{#Android#android.enableProguard}}.label", "Enable proguard"); set("{{#Android#android.enableProguard}}.type", "Checkbox"); set("{{#Android#android.enableProguard}}.description", "Boolean true/false defaults to true. Allows disabling the proguard obfuscation even on release builds, notice that this isn't recommended"); + } + if (!handWritten.contains("android.gradleDep")) { set("{{#Android#android.gradleDep}}.label", "Gradle dep"); set("{{#Android#android.gradleDep}}.type", "TextArea"); set("{{#Android#android.gradleDep}}.description", "Gradle dependency statements to add to the app module, such as implementation 'com.example:lib:1.0'."); + } + if (!handWritten.contains("android.hideStatusBar")) { set("{{#Android#android.hideStatusBar}}.label", "Hide status bar"); set("{{#Android#android.hideStatusBar}}.type", "Checkbox"); set("{{#Android#android.hideStatusBar}}.description", "Hides the Android status bar."); + } + if (!handWritten.contains("android.installLocation")) { set("{{#Android#android.installLocation}}.label", "Install location"); set("{{#Android#android.installLocation}}.type", "Select"); set("{{#Android#android.installLocation}}.values", "auto,internalOnly,preferExternal"); set("{{#Android#android.installLocation}}.description", "Maps to android:installLocation manifest entry defaults to auto. Can also be set to internalOnly or preferExternal."); + } + if (!handWritten.contains("android.licenseKey")) { set("{{#Android#android.licenseKey}}.label", "License key"); set("{{#Android#android.licenseKey}}.type", "TextField"); set("{{#Android#android.licenseKey}}.description", "The license key for the Android app, this is required if you use in-app purchase on Android"); + } + if (!handWritten.contains("android.min_sdk_version")) { set("{{#Android#android.min_sdk_version}}.label", "Min sdk version"); set("{{#Android#android.min_sdk_version}}.type", "TextField"); set("{{#Android#android.min_sdk_version}}.description", "The least SDK required to run this app, the default value changes based on functionality but can be as low as 7. This corresponds to the XML attribute `android:minSdkVersion`."); + } + if (!handWritten.contains("android.multidex")) { set("{{#Android#android.multidex}}.label", "Multidex"); set("{{#Android#android.multidex}}.type", "Checkbox"); set("{{#Android#android.multidex}}.description", "Boolean true/false defaults to false. Multidex allows Android binaries to reference more than 65536 methods. This slows builds a bit so you have it off by default but if you get a build error mentioning this limit you should turn this on."); + } + if (!handWritten.contains("android.newFirebaseMessaging")) { set("{{#Android#android.newFirebaseMessaging}}.label", "New firebase messaging"); set("{{#Android#android.newFirebaseMessaging}}.type", "Checkbox"); set("{{#Android#android.newFirebaseMessaging}}.description", "Uses the current Firebase Cloud Messaging integration. Requires AndroidX and Gradle 8.13 or newer."); + } + if (!handWritten.contains("android.proguardKeep")) { set("{{#Android#android.proguardKeep}}.label", "Proguard keep"); set("{{#Android#android.proguardKeep}}.type", "TextArea"); set("{{#Android#android.proguardKeep}}.description", "Arguments for the keep option in proguard allowing you to keep a pattern of files for example, `-keep class com.mypackage.ProblemClass { *; }`"); + } + if (!handWritten.contains("android.release")) { set("{{#Android#android.release}}.label", "Release"); set("{{#Android#android.release}}.type", "Checkbox"); set("{{#Android#android.release}}.description", "true/false defaults to true - indicates whether to include the release version in the build"); + } + if (!handWritten.contains("android.repositories")) { set("{{#Android#android.repositories}}.label", "Repositories"); set("{{#Android#android.repositories}}.type", "TextArea"); set("{{#Android#android.repositories}}.description", "Extra Gradle repositories to resolve dependencies from."); + } + if (!handWritten.contains("android.targetSDKVersion")) { set("{{#Android#android.targetSDKVersion}}.label", "Target sDKVersion"); set("{{#Android#android.targetSDKVersion}}.type", "TextField"); set("{{#Android#android.targetSDKVersion}}.description", "Indicates the Android SDK used to compile the Android build defaults to 21. Notice that not all targets will work since the source might have some limitations and not all SDK targets are installed on the build servers."); + } + if (!handWritten.contains("and.themeMode")) { set("{{#Android#and.themeMode}}.label", "Theme mode"); set("{{#Android#and.themeMode}}.type", "Select"); set("{{#Android#and.themeMode}}.values", "auto,modern,hololight,legacy"); set("{{#Android#and.themeMode}}.description", "`auto`, `modern` / `material`, `hololight` (default for existing apps), `legacy`. `auto` and `modern` / `material` opt in to the CSS-generated Android Material 3 theme from `native-themes/android-material/theme.css`. `hololight` is Android Holo Light (what the framework shipped on API 14+ before this refactor). `legacy` loads the pre-Holo Android theme. The legacy alias `cn1.androidTheme` is still accepted, and `and.hololight=true` still maps to `hololight`. The default stays on `hololight` for existing apps until you flip in a future release."); + } + if (!handWritten.contains("android.topDependency")) { set("{{#Android#android.topDependency}}.label", "Top dependency"); set("{{#Android#android.topDependency}}.type", "TextArea"); set("{{#Android#android.topDependency}}.description", "Statements added to the top-level Gradle build file rather than the app module."); + } + if (!handWritten.contains("android.useAndroidX")) { set("{{#Android#android.useAndroidX}}.label", "Use android x"); set("{{#Android#android.useAndroidX}}.type", "Checkbox"); set("{{#Android#android.useAndroidX}}.description", "Use Android X instead of support libraries. This will also run a find/replace on all source files to replace support libraries and artifacts with AndroidX equivalents."); + } + if (!handWritten.contains("android.xapplication")) { set("{{#Android#android.xapplication}}.label", "Xapplication"); set("{{#Android#android.xapplication}}.type", "TextArea"); set("{{#Android#android.xapplication}}.description", "defaults to an empty string. Allows developers of native Android code to add text within the application block to define things such as widgets, services etc."); + } + if (!handWritten.contains("android.xgradle")) { set("{{#Android#android.xgradle}}.label", "Xgradle"); set("{{#Android#android.xgradle}}.type", "TextArea"); set("{{#Android#android.xgradle}}.description", "Arbitrary text spliced into the generated app-module Gradle file."); + } + if (!handWritten.contains("android.xpermissions")) { set("{{#Android#android.xpermissions}}.label", "Xpermissions"); set("{{#Android#android.xpermissions}}.type", "TextArea"); set("{{#Android#android.xpermissions}}.description", "more permissions for the Android manifest"); + } set("{{@Desktop}}.label", "Desktop"); + if (!handWritten.contains("desktop.adaptToRetina")) { set("{{#Desktop#desktop.adaptToRetina}}.label", "Adapt to retina"); set("{{#Desktop#desktop.adaptToRetina}}.type", "Checkbox"); set("{{#Desktop#desktop.adaptToRetina}}.description", "Boolean true/false defaults to true. When set to true some values will ve implicitly doubled to deal with retina displays and icons etc. Will use higher DPI's"); + } + if (!handWritten.contains("desktop.fullscreen")) { set("{{#Desktop#desktop.fullscreen}}.label", "Fullscreen"); set("{{#Desktop#desktop.fullscreen}}.type", "Checkbox"); set("{{#Desktop#desktop.fullscreen}}.description", "Starts the desktop build in full-screen mode."); + } + if (!handWritten.contains("desktop.height")) { set("{{#Desktop#desktop.height}}.label", "Height"); set("{{#Desktop#desktop.height}}.type", "TextField"); set("{{#Desktop#desktop.height}}.description", "Height in pixels for the form in desktop builds, will be doubled for retina grade displays. Defaults to 600."); + } + if (!handWritten.contains("desktop.interactiveScrollbars")) { set("{{#Desktop#desktop.interactiveScrollbars}}.label", "Interactive scrollbars"); set("{{#Desktop#desktop.interactiveScrollbars}}.type", "Checkbox"); set("{{#Desktop#desktop.interactiveScrollbars}}.description", "Enables grab-able, click-to-page desktop scrollbars."); + } + if (!handWritten.contains("desktop.resizable")) { set("{{#Desktop#desktop.resizable}}.label", "Resizable"); set("{{#Desktop#desktop.resizable}}.type", "Checkbox"); set("{{#Desktop#desktop.resizable}}.description", "Boolean true/false defaults to true. Indicates whether the UI in the desktop build is resizable"); + } + if (!handWritten.contains("desktop.titleBar")) { set("{{#Desktop#desktop.titleBar}}.label", "Title bar"); set("{{#Desktop#desktop.titleBar}}.type", "Select"); set("{{#Desktop#desktop.titleBar}}.values", "native,custom,toolbar"); set("{{#Desktop#desktop.titleBar}}.description", "How the desktop window is framed: native for the OS title bar and menu bar, custom for an undecorated window with a Codename One drawn title bar, or toolbar for the legacy in-app Toolbar. An unrecognized value falls back to native with a warning."); + } + if (!handWritten.contains("desktop.width")) { set("{{#Desktop#desktop.width}}.label", "Width"); set("{{#Desktop#desktop.width}}.type", "TextField"); set("{{#Desktop#desktop.width}}.description", "Width in pixels for the form in desktop builds, will be doubled for retina grade displays. Defaults to 800."); + } set("{{@OnDeviceDebug}}.label", "On-Device Debugging"); + if (!handWritten.contains("android.onDeviceDebug")) { set("{{#OnDeviceDebug#android.onDeviceDebug}}.label", "Android"); set("{{#OnDeviceDebug#android.onDeviceDebug}}.type", "Checkbox"); set("{{#OnDeviceDebug#android.onDeviceDebug}}.description", "Boolean true/false defaults to false. When `true`, the generated `AndroidManifest.xml` is marked `android:debuggable=\"true\"`, R8/proguard is disabled, and the build is pinned to debug-only (`android.release` is forced off and `android.debug` is forced on) so a stray hint can't ship a release-signed APK that's `debuggable=\"true\"`. Pair with the `cn1:android-on-device-debugging` Maven goal (or the bundled IntelliJ run configs) to install, launch, forward JDWP, and stream logcat through adb. Has no effect on builds that don't carry it -- release builds are unaffected. See the On-Device Debugging (Android) chapter for the full flow."); + } + if (!handWritten.contains("ios.onDeviceDebug")) { set("{{#OnDeviceDebug#ios.onDeviceDebug}}.label", "Ios"); set("{{#OnDeviceDebug#ios.onDeviceDebug}}.type", "Checkbox"); set("{{#OnDeviceDebug#ios.onDeviceDebug}}.description", "Boolean true/false defaults to false. When `true`, the iOS build links a small JDWP listener thread (`cn1_debugger`) into the binary and the ParparVM translator emits source-line and locals metadata so a desktop proxy can serve the running app to any JDWP-speaking debugger. Has no effect on release builds. See the On-Device Debugging (iOS) chapter for the full flow."); + } + if (!handWritten.contains("ios.onDeviceDebug.proxyHost")) { set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyHost}}.label", "Ios proxy host"); set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyHost}}.type", "TextField"); set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyHost}}.description", "Hostname or IP address the device-side listener dials to reach the desktop proxy. Default `127.0.0.1` (correct for the native iOS simulator). For a physical device, set this to the developer laptop's LAN IP. Has no effect unless `ios.onDeviceDebug=true`."); + } + if (!handWritten.contains("ios.onDeviceDebug.proxyPort")) { set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyPort}}.label", "Ios proxy port"); set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyPort}}.type", "TextField"); set("{{#OnDeviceDebug#ios.onDeviceDebug.proxyPort}}.description", "TCP port on `ios.onDeviceDebug.proxyHost` where the proxy is listening for the device. Default `55333`. Has no effect unless `ios.onDeviceDebug=true`."); + } + if (!handWritten.contains("ios.onDeviceDebug.waitForAttach")) { set("{{#OnDeviceDebug#ios.onDeviceDebug.waitForAttach}}.label", "Ios wait for attach"); set("{{#OnDeviceDebug#ios.onDeviceDebug.waitForAttach}}.type", "Checkbox"); set("{{#OnDeviceDebug#ios.onDeviceDebug.waitForAttach}}.description", "Boolean true/false defaults to false. When `true`, the app blocks at startup until the proxy connects and the IDE tells the VM to continue. Useful when the breakpoint to investigate fires during app boot. Has no effect unless `ios.onDeviceDebug=true`."); + } set("{{@Build}}.label", "General"); + if (!handWritten.contains("facebook.appId")) { set("{{#Build#facebook.appId}}.label", "Facebook app id"); set("{{#Build#facebook.appId}}.type", "TextField"); set("{{#Build#facebook.appId}}.description", "The application ID for an app that requires native Facebook login integration, this defaults to null which means native Facebook support shouldn't be in the app"); + } + if (!handWritten.contains("gcm.sender_id")) { set("{{#Build#gcm.sender_id}}.label", "Gcm sender id"); set("{{#Build#gcm.sender_id}}.type", "TextField"); set("{{#Build#gcm.sender_id}}.description", "The Android/chrome push identifier, see the push section for more details"); + } + if (!handWritten.contains("nativeTheme")) { set("{{#Build#nativeTheme}}.label", "Native theme"); set("{{#Build#nativeTheme}}.type", "Select"); set("{{#Build#nativeTheme}}.values", "modern,legacy,custom"); set("{{#Build#nativeTheme}}.description", "`modern`, `legacy`, `custom` (default unset). Cross-platform override that sets both `ios.themeMode` and `and.themeMode` together when those aren't set explicitly. `modern` = liquid glass + Material 3, `legacy` = iOS 7 flat + Holo Light, `custom` disables the framework native theme entirely. The legacy alias `cn1.nativeTheme` is still accepted."); + } + if (!handWritten.contains("noExtraResources")) { set("{{#Build#noExtraResources}}.label", "No extra resources"); set("{{#Build#noExtraResources}}.type", "Checkbox"); set("{{#Build#noExtraResources}}.description", "true/false (defaults to false). Blocks codename one from injecting its own resources when set to true, the only effect this has is in slightly reducing archive size. This might have adverse effects on some features of Codename One so it isn't recommended."); + } set("{{@Hardening}}.label", "App Hardening"); + if (!handWritten.contains("harden.allowUnhardenedLocalBuild")) { set("{{#Hardening#harden.allowUnhardenedLocalBuild}}.label", "Allow unhardened local build"); set("{{#Hardening#harden.allowUnhardenedLocalBuild}}.type", "Checkbox"); set("{{#Hardening#harden.allowUnhardenedLocalBuild}}.description", "Permits a local or source build to run with hardening requested but not applied. Without it such a build is refused, so a hardened app is never shipped from a target that can't actually harden it."); + } + if (!handWritten.contains("harden.controlFlow")) { set("{{#Hardening#harden.controlFlow}}.label", "Control flow"); set("{{#Hardening#harden.controlFlow}}.type", "Select"); set("{{#Hardening#harden.controlFlow}}.values", "off,on"); set("{{#Hardening#harden.controlFlow}}.description", "Overrides control-flow obfuscation independently of harden.level."); + } + if (!handWritten.contains("harden.keep")) { set("{{#Hardening#harden.keep}}.label", "Keep"); set("{{#Hardening#harden.keep}}.type", "TextArea"); set("{{#Hardening#harden.keep}}.description", "Keep rules in ProGuard syntax, one per line, for classes that are resolved by name at runtime and so can't be found by the automatic analysis. Same syntax as android.proguardKeep, so existing rules port directly. Rules are separated by newlines only, because a semicolon is legal inside a rule body such as { *; }."); + } + if (!handWritten.contains("harden.level")) { set("{{#Hardening#harden.level}}.label", "Level"); set("{{#Hardening#harden.level}}.type", "Select"); set("{{#Hardening#harden.level}}.values", "off,standard,aggressive,paranoid"); set("{{#Hardening#harden.level}}.description", "Master switch for app hardening: off, standard, aggressive or paranoid. An unrecognized value fails the build rather than being treated as off."); + } + if (!handWritten.contains("harden.rename")) { set("{{#Hardening#harden.rename}}.label", "Rename"); set("{{#Hardening#harden.rename}}.type", "Checkbox"); set("{{#Hardening#harden.rename}}.description", "Overrides symbol renaming independently of harden.level."); + } + if (!handWritten.contains("harden.strings")) { set("{{#Hardening#harden.strings}}.label", "Strings"); set("{{#Hardening#harden.strings}}.type", "Select"); set("{{#Hardening#harden.strings}}.values", "off,constants,all"); set("{{#Hardening#harden.strings}}.description", "Overrides string obfuscation independently of harden.level: off, constants or all."); + } } /** Idempotent setter: does not overwrite user or project-level metadata. */ diff --git a/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintSchemaDefaults.java b/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintSchemaDefaults.java index 1f709f35387..f85a6fc37e9 100644 --- a/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintSchemaDefaults.java +++ b/Ports/JavaSE/src/com/codename1/impl/javase/BuildHintSchemaDefaults.java @@ -243,8 +243,32 @@ static void register() { BuildHintCatalogDefaults.register(); } + /** + * The hints this class describes by hand. + * + *

{@link BuildHintCatalogDefaults} consults it so the two never describe + * the same hint. The group name is part of the property key, so a hint + * registered under both {@code hardening} and {@code Hardening} is not + * overwritten -- it is a second group, and the editor renders both, giving + * the user duplicate controls for one setting.

+ */ + private static final java.util.Set DECLARED = new java.util.HashSet(); + + /** Hint names {@link #register} describes, for the generated companion to skip. */ + static java.util.Set declaredHints() { + return java.util.Collections.unmodifiableSet(DECLARED); + } + /** Idempotent setter: does not overwrite user / project-level hint metadata. */ private static void set(String suffix, String value) { + int hash = suffix.indexOf('#'); + if (suffix.startsWith("{{#") && hash >= 0) { + int second = suffix.indexOf('#', hash + 1); + int close = suffix.indexOf("}}", second + 1); + if (second > 0 && close > second) { + DECLARED.add(suffix.substring(second + 1, close)); + } + } String key = "codename1.arg." + suffix; if (System.getProperty(key) == null) { System.setProperty(key, value); diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java index a6f3017d02a..067e2c4c14f 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java @@ -484,18 +484,25 @@ private static String simulatorSchemaSource(Map sb.append(" * BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and re-run\n"); sb.append(" * scripts/gen-build-hint-annotations.sh.

\n"); sb.append(" *\n"); - sb.append(" *

Registered after {@link BuildHintSchemaDefaults}, whose hand-written\n"); - sb.append(" * entries take precedence because the shared setter never overwrites.

\n"); + sb.append(" *

Registered after {@link BuildHintSchemaDefaults} and skipping every hint\n"); + sb.append(" * that class already describes. Precedence cannot be left to the setter:\n"); + sb.append(" * the group name is part of the property key, so registering harden.level\n"); + sb.append(" * under both `hardening` and `Hardening` does not overwrite anything -- it\n"); + sb.append(" * makes a second group, and the editor renders both, giving the user\n"); + sb.append(" * duplicate controls for one setting.

\n"); sb.append(" */\n"); sb.append("final class BuildHintCatalogDefaults {\n\n"); sb.append(" private BuildHintCatalogDefaults() {\n }\n\n"); sb.append(" static void register() {\n"); + sb.append(" java.util.Set handWritten = BuildHintSchemaDefaults.declaredHints();\n"); for (Map.Entry> e : byGroup.entrySet()) { String group = e.getKey().annotationSimpleName(); sb.append("\n set(\"{{@").append(group).append("}}.label\", ") .append(quote(toAscii(groupLabel(e.getKey())))).append(");\n"); for (BuildHints.Hint h : e.getValue()) { String key = "{{#" + group + "#" + h.name() + "}}"; + sb.append(" if (!handWritten.contains(\"").append(esc(h.name())) + .append("\")) {\n"); sb.append(" set(\"").append(key).append(".label\", ") .append(quote(humanize(h.attr()))).append(");\n"); sb.append(" set(\"").append(key).append(".type\", \"") @@ -515,6 +522,7 @@ private static String simulatorSchemaSource(Map sb.append(" set(\"").append(key).append(".description\", ") .append(quote(toAscii(h.doc()))).append(");\n"); } + sb.append(" }\n"); } } sb.append(" }\n\n"); diff --git a/maven/integration-tests/build-hint-annotations-test.sh b/maven/integration-tests/build-hint-annotations-test.sh index b5b977b4523..3160a49ad41 100755 --- a/maven/integration-tests/build-hint-annotations-test.sh +++ b/maven/integration-tests/build-hint-annotations-test.sh @@ -76,13 +76,21 @@ set +e set -e MERGED=common/target/codenameone/antProject/codenameone_settings.properties test -f $MERGED || MERGED=javase/target/codenameone/antProject/codenameone_settings.properties -if [ -f "$MERGED" ]; then - grep -q "codename1.arg.ios.pods=Alamofire,SwiftyJSON" $MERGED \ - || { echo "FAIL: annotation hints did not reach the build request"; cat $MERGED; exit 1; } - echo "OK: annotation hints reached $MERGED" -else - echo "NOTE: no build request was written for this target; skipping that assertion" +# Do not treat an absent file as "nothing to check". This is the only assertion +# that the annotations reach the build request at all -- the checks above cover +# emission and the one below covers the conflict -- so if the probe stops +# producing a merged settings file, through a change in goal ordering, target +# validation or the merge itself, the test has to fail rather than quietly skip +# the thing it exists to prove. +if [ ! -f "$MERGED" ]; then + echo "FAIL: no build request was written; the annotation merge could not be verified." + echo " Looked for common/ and javase/target/codenameone/antProject/codenameone_settings.properties" + tail -40 /tmp/cn1-hints-build.log + exit 1 fi +grep -q "codename1.arg.ios.pods=Alamofire,SwiftyJSON" $MERGED \ + || { echo "FAIL: annotation hints did not reach the build request"; cat $MERGED; exit 1; } +echo "OK: annotation hints reached $MERGED" echo "--- declaring the same hint twice must fail ---" echo "codename1.arg.ios.teamId=FROMFILE" >> $SETTINGS From 586e6bc3fb7d5e7ade62cb7a052c3ed97c97d88f Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 11:52:11 +0300 Subject: [PATCH 14/23] Prove the annotations are processed instead of predicting it Four rounds of review went into guessing, from the POM, whether process-annotations would run: it can be bound on the wrong module, bound to a phase with no compiled classes, skipped outright, or skipped through a property expression the model text does not resolve. Each fix closed one case and the next review found another, which is what a static prediction of another mojo's behaviour is going to keep doing. The goal now applies the whole migration, runs process-classes over the module that holds the main class, and checks that every migrated hint came back out of the emitted resource. If any did not, both files are put back exactly as they were and the failure says what was missing. Whatever the next way to not-run turns out to be, the answer is still correct. Both files have to move together before that check: leaving the properties in place while the annotations are added is itself the duplicate-declaration case, so the build would fail for that reason and never say whether processing works. The first version of this change had that wrong, and the verification caught it. Verified on a generated project: 7 hints in, 6 migrated and confirmed emitted, java.version correctly kept. With the binding removed the goal refuses and both files come back byte-identical. The Settings tool has the same problem from the other side. It read ownership only from the emitted resource, so in the window right after a migration -- the source declares the annotations, no build has run -- every hint looked unowned and Add was offered for one the annotations already set. It now falls back to reading the annotations off the main class, matching attribute names at the top level of each annotation so a comma, bracket or equals sign inside a value cannot register as one. Co-Authored-By: Claude Opus 5 (1M context) --- .../maven/MigrateBuildHintsMojo.java | 236 ++++++++---------- .../MigrateBuildHintsPropertyParsingTest.java | 63 ----- .../settings/CodenameOneSettings.java | 143 ++++++++++- .../settings/BuildHintCatalogTest.java | 38 +++ 4 files changed, 291 insertions(+), 189 deletions(-) diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index 5cccbd6c5f6..0bcfabe7ee9 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -26,6 +26,11 @@ import com.codename1.build.shared.HintType; import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.shared.invoker.DefaultInvocationRequest; +import org.apache.maven.shared.invoker.DefaultInvoker; +import org.apache.maven.shared.invoker.InvocationRequest; +import org.apache.maven.shared.invoker.InvocationResult; +import org.apache.maven.shared.invoker.MavenInvocationException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; @@ -99,29 +104,6 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException throw new MojoExecutionException("No codenameone_settings.properties in " + projectDir); } - // Nothing turns an annotation back into a build hint except the - // process-annotations goal, and a mojo's defaultPhase does not bind it to - // a project -- the project's own POM has to. Migrating without that - // binding deletes working properties and replaces them with annotations no - // goal ever reads, so the hints disappear from the build silently. - if (!processAnnotationsIsBound()) { - File owner = getCN1ProjectDir(); - throw new MojoFailureException("The module that holds the main class" - + (owner == null ? "" : " (" + owner + ")") - + " does not run the cn1 process-annotations goal, so build hint annotations " - + "would never be turned back into the codename1.arg.* pairs the builders " - + "read, and migrating would silently drop them. The goal only scans the " - + "module it is bound to, so binding it elsewhere in the reactor does not " - + "help.\n\nAdd it to that module's POM first:\n" - + " \n" - + " cn1-process-classes\n" - + " process-classes\n" - + " \n" - + " process-annotations\n" - + " \n" - + " "); - } - // The annotations ship in codenameone-core. A project pinned to a release // that predates them would migrate cleanly here and then fail to compile, // so refuse rather than hand back a broken project. @@ -223,13 +205,71 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException + "migrated lines from " + settingsFile.getName() + "."); } + // Add the annotations, prove the build actually turns them back into hints, + // and only then delete the properties. Deciding that from the POM instead + // meant guessing whether process-annotations would run -- and the goal is + // skippable, bindable to a phase with no compiled classes, bindable to the + // wrong module, and skippable through a property expression. Observing the + // emitted resource answers all of those at once, and answers correctly for + // whatever the next way to not-run turns out to be. + // Apply the whole migration, prove the build turns the annotations back + // into hints, and roll both files back if it does not. + // + // Both files have to move together before the check: leaving the + // properties in place while the annotations are added *is* the + // duplicate-declaration case, so the build would fail for that reason and + // never tell us whether processing works at all. + // + // Deciding this from the POM instead meant guessing whether + // process-annotations would run, and the goal is skippable, bindable to a + // phase with no compiled classes, bindable to the wrong module, and + // skippable through a property expression. Observing the emitted resource + // answers all of those at once, and answers correctly for whatever the + // next way to not-run turns out to be. + File source = new File(mainSource); + String originalSource; + String originalSettings; try { - insertAnnotations(new File(mainSource), rendered.toString(), + originalSource = read(source); + originalSettings = read(settingsFile); + insertAnnotations(source, rendered.toString(), settings.getProperty("codename1.mainName", "").trim()); removeMigratedLines(settingsFile, migratedKeys); } catch (IOException ex) { throw new MojoExecutionException("Migration failed: " + ex.getMessage(), ex); } + + String missing = verifyAnnotationsAreProcessed(projectDir, migratedKeys); + if (missing != null) { + StringBuilder restoreFailed = new StringBuilder(); + try { + write(source, originalSource); + } catch (IOException ex) { + restoreFailed.append("\nCould not restore ").append(source).append(": ") + .append(ex.getMessage()); + } + try { + writeProperties(settingsFile, originalSettings); + } catch (IOException ex) { + restoreFailed.append("\nCould not restore ").append(settingsFile).append(": ") + .append(ex.getMessage()); + } + throw new MojoFailureException("The annotations were added but the build did not turn " + + "them into build hints, so " + source.getName() + " and " + + settingsFile.getName() + " have been put back as they were.\n\n" + + missing + "\n\nThe usual cause is that this module does not run the cn1 " + + "process-annotations goal, or runs it skipped or before compile. Add it and " + + "try again:\n" + + " \n" + + " cn1-process-classes\n" + + " process-classes\n" + + " \n" + + " process-annotations\n" + + " \n" + + " " + + restoreFailed); + } + getLog().info("cn1: migrated " + migratedKeys.size() + " build hint(s) into " + new File(mainSource).getName()); } @@ -242,120 +282,61 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException * goal is an aggregator, so {@code project} is the root POM while the binding * lives in the common module.

*/ - private boolean processAnnotationsIsBound() { - return moduleOwningTheMainClass() != null; - } - /** - * The reactor module that both holds the main class and runs - * {@code process-annotations} over it, or null. - * - *

Checking the reactor as a whole is not enough. {@code - * ProcessAnnotationsMojo} scans only the output directory of the module it is - * bound to, so a binding on a platform or utility module never sees the main - * class that {@code common} compiles. The migration would then delete the - * properties and leave annotations nothing ever reads.

+ * Runs the project's own build over the module that holds the main class and + * checks that every migrated hint came back out of it. * - *

The owning module is the one whose base directory is the Codename One - * project directory -- the directory holding - * {@code codenameone_settings.properties}, which is also where - * {@link #findMainClassSource} looks.

+ * @return null when all of them did, otherwise a description of what is + * missing, suitable for showing to the developer */ - private org.apache.maven.project.MavenProject moduleOwningTheMainClass() { - File projectDir = getCN1ProjectDir(); - if (projectDir == null) { - return null; - } - java.util.List projects = reactorProjects; - if (projects == null || projects.isEmpty()) { - projects = java.util.Collections.singletonList(project); - } - for (org.apache.maven.project.MavenProject p : projects) { - if (p.getBasedir() == null || !sameDirectory(p.getBasedir(), projectDir)) { - continue; + private String verifyAnnotationsAreProcessed(File projectDir, List migratedKeys) { + getLog().info("cn1: building " + projectDir.getName() + + " to confirm the annotations produce the hints..."); + File pom = new File(projectDir, "pom.xml"); + InvocationRequest request = new DefaultInvocationRequest(); + request.setPomFile(pom.isFile() ? pom : new File(project.getBasedir(), "pom.xml")); + request.setGoals(Collections.singletonList("process-classes")); + Properties props = new Properties(); + props.setProperty("skipTests", "true"); + request.setProperties(props); + request.setBatchMode(true); + try { + InvocationResult result = new DefaultInvoker().execute(request); + if (result.getExitCode() != 0) { + return "The build failed with exit code " + result.getExitCode() + + ", so the annotations could not be checked."; } - return bindsProcessAnnotations(p) ? p : null; + } catch (MavenInvocationException ex) { + return "The build could not be run (" + ex.getMessage() + + "), so the annotations could not be checked."; } - return null; - } - private static boolean sameDirectory(File a, File b) { - try { - return a.getCanonicalFile().equals(b.getCanonicalFile()); - } catch (IOException ex) { - return a.getAbsoluteFile().equals(b.getAbsoluteFile()); + File emitted = new File(projectDir, "target/classes/" + ANNOTATION_HINTS_RESOURCE); + if (!emitted.isFile()) { + return "No " + ANNOTATION_HINTS_RESOURCE + " was written under " + + projectDir.getName() + "/target/classes."; } - } - - /** - * Whether this module runs {@code process-annotations} somewhere it can - * actually see compiled classes. - * - *

Being declared is not enough. {@code ProcessAnnotationsMojo} returns - * immediately when {@code skip} is set, and again when its output directory - * does not exist -- which is the case for every phase before {@code compile}. - * An execution that is skipped, or bound to {@code generate-sources}, emits - * no annotation resource at all, so migrating against it would delete the - * working properties and leave nothing behind.

- */ - static boolean bindsProcessAnnotations(org.apache.maven.project.MavenProject p) { - java.util.List plugins = p.getBuildPlugins(); - if (plugins == null) { - return false; + Properties produced = new Properties(); + try (FileInputStream in = new FileInputStream(emitted)) { + produced.load(in); + } catch (IOException ex) { + return "Could not read " + emitted + ": " + ex.getMessage(); } - for (org.apache.maven.model.Plugin plugin : plugins) { - if (!"codenameone-maven-plugin".equals(plugin.getArtifactId())) { - continue; - } - for (org.apache.maven.model.PluginExecution e : plugin.getExecutions()) { - if (e.getGoals() == null || !e.getGoals().contains("process-annotations")) { - continue; - } - if (!phaseSeesCompiledClasses(e.getPhase())) { - continue; - } - if (isSkipped(e.getConfiguration()) || isSkipped(plugin.getConfiguration())) { - continue; - } - return true; + List absent = new ArrayList(); + for (String key : migratedKeys) { + if (produced.getProperty(key) == null) { + absent.add(key); } } - return false; - } - - /** - * The default lifecycle from {@code compile} onward -- the phases by which - * {@code target/classes} exists. - */ - private static final java.util.List PHASES_WITH_CLASSES = - java.util.Arrays.asList("compile", "process-classes", - "generate-test-sources", "process-test-sources", - "generate-test-resources", "process-test-resources", - "test-compile", "process-test-classes", "test", - "prepare-package", "package", - "pre-integration-test", "integration-test", "post-integration-test", - "verify", "install", "deploy"); - - /** - * @param phase the execution's phase, or null to accept the goal's own - * default of {@code process-classes} - */ - private static boolean phaseSeesCompiledClasses(String phase) { - if (phase == null || phase.trim().length() == 0) { - return true; + if (!absent.isEmpty()) { + return "These hints were annotated but did not come back out of the build: " + absent; } - return PHASES_WITH_CLASSES.contains(phase.trim().toLowerCase()); + return null; } - /** Reads {@code true} out of a plugin or execution configuration. */ - private static boolean isSkipped(Object configuration) { - if (!(configuration instanceof org.codehaus.plexus.util.xml.Xpp3Dom)) { - return false; - } - org.codehaus.plexus.util.xml.Xpp3Dom skip = - ((org.codehaus.plexus.util.xml.Xpp3Dom) configuration).getChild("skip"); - return skip != null && "true".equalsIgnoreCase(String.valueOf(skip.getValue()).trim()); - } + /** Name of the resource the annotation processor emits into target/classes. */ + private static final String ANNOTATION_HINTS_RESOURCE = + "META-INF/codenameone/build-hints.properties"; /** * Whether the codenameone-core on this project's compile classpath actually @@ -742,6 +723,11 @@ private static String read(File f) throws IOException { return sb.toString(); } + /** Restores a source file after a failed migration. */ + private static void writeSource(File f, String content) throws IOException { + write(f, content); + } + private static void write(File f, String content) throws IOException { Writer w = new OutputStreamWriter(new FileOutputStream(f), "UTF-8"); try { diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java index 61db8909385..159ebd3a080 100644 --- a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java @@ -22,15 +22,9 @@ */ package com.codename1.maven; -import org.apache.maven.model.Plugin; -import org.apache.maven.model.PluginExecution; -import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.util.xml.Xpp3Dom; import org.junit.Test; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNull; /// Covers the properties parsing in `MigrateBuildHintsMojo`. @@ -112,63 +106,6 @@ public void aDefaultPackageSourceStillGetsAUsableAnchor() { MigrateBuildHintsMojo.classDeclarationIndex(src, false, "MyApp")); } - /// process-annotations scans only the output of the module it is bound to, so - /// a binding on a platform or utility module never sees the main class that - /// the common module compiles. Accepting one would let the migration delete - /// the properties and leave annotations nothing reads. - @Test - public void onlyAnEnabledExecutionOnTheOwningModuleCounts() { - assertTrue(MigrateBuildHintsMojo.bindsProcessAnnotations( - moduleBinding("process-annotations", "process-classes", false))); - // No phase means the goal's own default, process-classes. - assertTrue(MigrateBuildHintsMojo.bindsProcessAnnotations( - moduleBinding("process-annotations", null, false))); - assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( - moduleBinding("css", "process-classes", false))); - // Declared but never run is the same as absent for this purpose. - assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( - moduleBinding("process-annotations", "none", false))); - } - - /// ProcessAnnotationsMojo returns immediately when skip is set, and again - /// when its output directory does not exist -- which is every phase before - /// compile. Such an execution emits no annotation resource, so migrating - /// against it would delete the properties and leave nothing behind. - @Test - public void anExecutionThatCannotSeeCompiledClassesDoesNotCount() { - assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( - moduleBinding("process-annotations", "generate-sources", false))); - assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( - moduleBinding("process-annotations", "process-resources", false))); - assertFalse(MigrateBuildHintsMojo.bindsProcessAnnotations( - moduleBinding("process-annotations", "process-classes", true))); - // compile is the earliest phase where target/classes exists. - assertTrue(MigrateBuildHintsMojo.bindsProcessAnnotations( - moduleBinding("process-annotations", "compile", false))); - } - - private static MavenProject moduleBinding(String goal, String phase, boolean skip) { - PluginExecution e = new PluginExecution(); - if (phase != null) { - e.setPhase(phase); - } - e.addGoal(goal); - if (skip) { - Xpp3Dom config = new Xpp3Dom("configuration"); - Xpp3Dom flag = new Xpp3Dom("skip"); - flag.setValue("true"); - config.addChild(flag); - e.setConfiguration(config); - } - Plugin plugin = new Plugin(); - plugin.setGroupId("com.codenameone"); - plugin.setArtifactId("codenameone-maven-plugin"); - plugin.addExecution(e); - MavenProject p = new MavenProject(); - p.getBuild().addPlugin(plugin); - return p; - } - @Test public void aValueOnlyLineHasNoSeparator() { assertEquals("bare", MigrateBuildHintsMojo.propertyKeyOf("bare")); diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java index 880a7f61bb1..02e0414c184 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java @@ -2101,7 +2101,12 @@ private java.util.Map loadAnnotationOwnedHints() { String url = ProjectIO.fsUrl(path); FileSystemStorage fs = FileSystemStorage.getInstance(); if (!fs.exists(url)) { - return out; + // Not built yet. Read the annotations off the source instead -- + // the window right after cn1:migrate-build-hints is exactly when + // the source declares them and no build has emitted anything, and + // treating them as unowned there would offer Add for a hint the + // annotations already set, which fails the next build. + return annotationOwnedHintsFromSource(); } in = fs.openInputStream(url); String text = Util.readToString(in, "ISO-8859-1"); @@ -2125,4 +2130,140 @@ private java.util.Map loadAnnotationOwnedHints() { } return out; } + + /// Reads the build hint annotations straight off the main class. + /// + /// Only the attribute *names* are needed -- what each hint is set to does not + /// matter, only that an annotation owns it -- so this scans the annotation + /// list above the class declaration for `name =` at the top level of each + /// annotation's parentheses and maps those to hint names through the catalog. + /// Values are skipped wholesale, so a comma or bracket inside a string cannot + /// confuse it. + private java.util.Map annotationOwnedHintsFromSource() { + java.util.Map out = new java.util.HashMap<>(); + String main = settings == null ? null : settings.get("codename1.mainName"); + String pkg = settings == null ? null : settings.get("codename1.packageName"); + if (binding == null || binding.projectDir() == null || main == null || main.isEmpty()) { + return out; + } + String rel = (pkg == null || pkg.isEmpty() ? "" : pkg.replace('.', '/') + "/") + main; + for (String ext : new String[]{".java", ".kt"}) { + for (String root : new String[]{"/src/main/java/", "/src/main/kotlin/", "/src/"}) { + String path = binding.projectDir() + root + rel + ext; + String text = readIfPresent(path); + if (text == null) { + continue; + } + collectAnnotationOwnedHints(text, out); + return out; + } + } + return out; + } + + private String readIfPresent(String path) { + InputStream in = null; + try { + String url = ProjectIO.fsUrl(path); + FileSystemStorage fs = FileSystemStorage.getInstance(); + if (!fs.exists(url)) { + return null; + } + in = fs.openInputStream(url); + return Util.readToString(in, "UTF-8"); + } catch (Exception ex) { + Log.e(ex); + return null; + } finally { + Util.cleanup(in); + } + } + + /// Maps every `@Group(attr = ...)` on the main class to the hints it sets. + static void collectAnnotationOwnedHints(String source, java.util.Map out) { + for (com.codename1.build.shared.BuildHints.Hint h : com.codename1.build.shared.BuildHints.entries()) { + if (!h.isAnnotated()) { + continue; + } + String marker = "@" + h.group().annotationSimpleName(); + int at = source.indexOf(marker); + while (at >= 0) { + int open = source.indexOf('(', at); + if (open < 0) { + break; + } + String args = balancedArgs(source, open); + if (args != null && declaresAttribute(args, h.attr())) { + out.put(com.codename1.build.shared.BuildHints.canonicalName(h.name()), + marker + "(" + h.attr() + ")"); + break; + } + at = source.indexOf(marker, at + marker.length()); + } + } + } + + /// The text inside the parentheses starting at `open`, or null when unbalanced. + private static String balancedArgs(String source, int open) { + int depth = 0; + boolean inString = false; + for (int i = open; i < source.length(); i++) { + char c = source.charAt(i); + if (inString) { + if (c == '\\') { + i++; + } else if (c == '"') { + inString = false; + } + continue; + } + if (c == '"') { + inString = true; + } else if (c == '(' || c == '{' || c == '[') { + depth++; + } else if (c == ')' || c == '}' || c == ']') { + depth--; + if (depth == 0) { + return source.substring(open + 1, i); + } + } + } + return null; + } + + /// Whether `args` assigns `attr` at the top level, ignoring anything inside a + /// nested value or a string. + private static boolean declaresAttribute(String args, String attr) { + int depth = 0; + boolean inString = false; + StringBuilder word = new StringBuilder(); + for (int i = 0; i < args.length(); i++) { + char c = args.charAt(i); + if (inString) { + if (c == '\\') { + i++; + } else if (c == '"') { + inString = false; + } + continue; + } + if (c == '"') { + inString = true; + } else if (c == '(' || c == '{' || c == '[') { + depth++; + } else if (c == ')' || c == '}' || c == ']') { + depth--; + } else if (depth == 0 && c == '=' && (i + 1 >= args.length() || args.charAt(i + 1) != '=')) { + if (word.toString().trim().equals(attr)) { + return true; + } + word.setLength(0); + } else if (depth == 0 && c == ',') { + word.setLength(0); + } else if (depth == 0) { + word.append(c); + } + } + return false; + } } diff --git a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java index 825cfd4d7dd..f41fbd9eb9a 100644 --- a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java +++ b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java @@ -157,6 +157,44 @@ public void aliasesResolveToTheirCanonicalName() { com.codename1.build.shared.BuildHints.canonicalName("ios.pods")); } + /** + * Right after cn1:migrate-build-hints the source declares the annotations and + * no build has emitted the manifest yet. Treating them as unowned there would + * offer Add for a hint the annotations already set, and the next build would + * fail on the duplicate declaration -- so the source is read directly. + */ + @Test + public void annotationsAreFoundInSourceBeforeTheProjectIsBuilt() { + String src = "package com.example;\n" + + "import com.codename1.annotations.buildhints.*;\n" + + "@Ios(pods = {\"A\", \"B\"}, teamId = \"T\")\n" + + "@Desktop(titleBar = DesktopTitleBar.NATIVE)\n" + + "public class MyApp extends Lifecycle {\n}\n"; + java.util.Map owned = new java.util.HashMap<>(); + CodenameOneSettings.collectAnnotationOwnedHints(src, owned); + assertEquals("@Ios(pods)", owned.get("ios.pods")); + assertEquals("@Ios(teamId)", owned.get("ios.teamId")); + assertEquals("@Desktop(titleBar)", owned.get("desktop.titleBar")); + assertTrue(owned.get("ios.objC") == null, "an attribute nobody set is not owned"); + } + + /** + * Attribute detection must not be fooled by a value that contains an equals + * sign, a comma or a bracket -- android.xpermissions is XML, and gradleDep + * entries carry both. + */ + @Test + public void valuesContainingSeparatorsDoNotCreatePhantomOwnership() { + String src = "@Android(xpermissions = \"\")\n" + + "public class MyApp {}\n"; + java.util.Map owned = new java.util.HashMap<>(); + CodenameOneSettings.collectAnnotationOwnedHints(src, owned); + assertEquals("@Android(xpermissions)", owned.get("android.xpermissions")); + assertTrue(owned.get("android.gradleDep") == null, + "nothing inside a string value may register as an attribute"); + assertTrue(owned.get("android.debug") == null); + } + @Test public void searchStillMatchesOnNameAndDescription() { BuildHintCatalog catalog = BuildHintCatalog.load(); From b1dff60641f3a488a39a598a17172f2e772a2c0b Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 14:17:12 +0300 Subject: [PATCH 15/23] Round-trip the rollback snapshot, and stop trusting a stale manifest The rollback snapshot was taken with the UTF-8 read helper and restored with the ISO-8859-1 writer, so any raw high byte in an unrelated property -- an accented codename1.displayName, say -- came back changed while the goal reported that both files were put back exactly as they were. It is snapshotted with the properties encoding now, and the two helpers are explicit about which encoding they use rather than one of them being the default. Verified on a generated project carrying a raw 0xE9: after a failed migration the settings file is byte-identical and the byte is still there. The Settings tool consulted the main-class source only when the emitted manifest was missing. The manifest is a build artifact and goes stale in both directions -- absent right after a migration, and out of date the moment an attribute is added to a project that was built earlier -- so a newly annotated hint looked unowned and Add wrote the duplicate declaration the next build refuses. The source is read every time now, because it is the only current statement of what the annotations declare, and the manifest is merged on top for its origins. The union is the safe direction: over-reporting ownership only withholds an editor, while under-reporting breaks the build. Co-Authored-By: Claude Opus 5 (1M context) --- .../maven/MigrateBuildHintsMojo.java | 21 +++++++++++++++++-- .../settings/CodenameOneSettings.java | 20 ++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index 0bcfabe7ee9..b59e42597de 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -231,7 +231,7 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException String originalSettings; try { originalSource = read(source); - originalSettings = read(settingsFile); + originalSettings = readProperties(settingsFile); insertAnnotations(source, rendered.toString(), settings.getProperty("codename1.mainName", "").trim()); removeMigratedLines(settingsFile, migratedKeys); @@ -709,9 +709,26 @@ private static void writeProperties(File f, String content) throws IOException { } } + /** + * Reads a properties file as ISO-8859-1, matching {@link #writeProperties}. + * + *

The rollback snapshot has to round-trip byte for byte. Taking it through + * the UTF-8 {@link #read} and restoring it with the ISO-8859-1 writer would + * mangle any raw high byte in an unrelated property -- an accented + * {@code codename1.displayName}, say -- while the goal reports that both + * files were put back as they were.

+ */ + private static String readProperties(File f) throws IOException { + return read(f, PROPERTIES_ENCODING); + } + private static String read(File f) throws IOException { + return read(f, "UTF-8"); + } + + private static String read(File f, String encoding) throws IOException { StringBuilder sb = new StringBuilder(); - BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8")); + BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(f), encoding)); try { int c; while ((c = r.read()) >= 0) { diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java index 02e0414c184..d2c7bfc2b9e 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java @@ -2098,15 +2098,23 @@ private java.util.Map loadAnnotationOwnedHints() { String path = binding.projectDir() + "/target/classes/META-INF/codenameone/build-hints.properties"; InputStream in = null; try { + // Always start from the source, because it is the only current + // statement of what the annotations declare. The manifest is a build + // artifact and goes stale in both directions: absent right after + // cn1:migrate-build-hints, and out of date the moment an attribute is + // added to a project that was built earlier. Trusting it alone left + // the newly annotated hint looking unowned, and Add then wrote the + // duplicate declaration the next build refuses. + // + // The manifest is merged in on top for its origins; the union is the + // safe direction, since over-reporting ownership only withholds an + // editor, while under-reporting breaks the build. + out.putAll(annotationOwnedHintsFromSource()); + String url = ProjectIO.fsUrl(path); FileSystemStorage fs = FileSystemStorage.getInstance(); if (!fs.exists(url)) { - // Not built yet. Read the annotations off the source instead -- - // the window right after cn1:migrate-build-hints is exactly when - // the source declares them and no build has emitted anything, and - // treating them as unowned there would offer Add for a hint the - // annotations already set, which fails the next build. - return annotationOwnedHintsFromSource(); + return out; } in = fs.openInputStream(url); String text = Util.readToString(in, "ISO-8859-1"); From 76cd1dcb5fa472a32dfdd2d670b1124ee9ea0abf Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 16:30:32 +0300 Subject: [PATCH 16/23] Preserve source bytes, and stop comments confusing the annotation scanner The main class was read and written as UTF-8, so a project whose sources use a different encoding had its whole file reinterpreted while the annotations were spliced in: a raw byte in a comment or a string literal came back changed even when the migration succeeded. Reading project.build.sourceEncoding would only narrow that to projects which declare it correctly. Instead both ends use ISO-8859-1, which maps every byte 0-255 to the same char, so decode -> splice ASCII -> encode reproduces the original bytes exactly whatever the real encoding is. The markers this code looks for -- package, import, the class declaration -- are ASCII, and every ASCII-compatible encoding decodes those identically under that scheme. Verified on a generated project whose main class carries three raw 0xE9 bytes in a comment, making it invalid UTF-8: all three survive the migration and the annotations are still inserted correctly. The Settings tool's source scanner skipped strings but not comments, so a comment carrying an unmatched delimiter -- @Ios(/* required for issue ( */ teamId = "x") -- lost the annotation's boundary and left teamId editable, which is the case that writes the duplicate declaration. It now skips line comments, block comments and character literals as well, through one shared helper used by both the balancer and the attribute scan. Co-Authored-By: Claude Opus 5 (1M context) --- .../maven/MigrateBuildHintsMojo.java | 22 ++++- .../settings/CodenameOneSettings.java | 80 +++++++++++++------ .../settings/BuildHintCatalogTest.java | 32 ++++++++ 3 files changed, 108 insertions(+), 26 deletions(-) diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index b59e42597de..40bdd1e880f 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -722,10 +722,28 @@ private static String readProperties(File f) throws IOException { return read(f, PROPERTIES_ENCODING); } + /** + * Reads a source file byte-transparently. + * + *

ISO-8859-1 maps every byte 0-255 to the same char, so decoding with it, + * splicing in text that is pure ASCII, and encoding back reproduces the + * original bytes exactly -- whatever the project's real source encoding is. + * Hard-coding UTF-8 here reinterpreted the whole file, so a raw byte in a + * comment or a string literal came back changed even when the migration + * succeeded, and reading {@code project.build.sourceEncoding} would only + * narrow that to projects that declare it correctly.

+ * + *

The markers this class searches for -- {@code package}, {@code import}, + * the class declaration -- are ASCII, and every ASCII-compatible encoding + * decodes them identically under this scheme.

+ */ private static String read(File f) throws IOException { - return read(f, "UTF-8"); + return read(f, SOURCE_BYTE_TRANSPARENT_ENCODING); } + /** See {@link #read(File)}: byte-transparent, not a claim about the file. */ + private static final String SOURCE_BYTE_TRANSPARENT_ENCODING = "ISO-8859-1"; + private static String read(File f, String encoding) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(f), encoding)); @@ -746,7 +764,7 @@ private static void writeSource(File f, String content) throws IOException { } private static void write(File f, String content) throws IOException { - Writer w = new OutputStreamWriter(new FileOutputStream(f), "UTF-8"); + Writer w = new OutputStreamWriter(new FileOutputStream(f), SOURCE_BYTE_TRANSPARENT_ENCODING); try { w.write(content); } finally { diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java index d2c7bfc2b9e..4e5d7405e62 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java @@ -2212,22 +2212,21 @@ static void collectAnnotationOwnedHints(String source, java.util.Map i) { + i = skipped - 1; continue; } - if (c == '"') { - inString = true; - } else if (c == '(' || c == '{' || c == '[') { + char c = source.charAt(i); + if (c == '(' || c == '{' || c == '[') { depth++; } else if (c == ')' || c == '}' || c == ']') { depth--; @@ -2240,28 +2239,23 @@ private static String balancedArgs(String source, int open) { } /// Whether `args` assigns `attr` at the top level, ignoring anything inside a - /// nested value or a string. + /// nested value, a string, a character literal or a comment. private static boolean declaresAttribute(String args, String attr) { int depth = 0; - boolean inString = false; StringBuilder word = new StringBuilder(); for (int i = 0; i < args.length(); i++) { - char c = args.charAt(i); - if (inString) { - if (c == '\\') { - i++; - } else if (c == '"') { - inString = false; - } + int skipped = skipNonCode(args, i); + if (skipped > i) { + i = skipped - 1; continue; } - if (c == '"') { - inString = true; - } else if (c == '(' || c == '{' || c == '[') { + char c = args.charAt(i); + if (c == '(' || c == '{' || c == '[') { depth++; } else if (c == ')' || c == '}' || c == ']') { depth--; - } else if (depth == 0 && c == '=' && (i + 1 >= args.length() || args.charAt(i + 1) != '=')) { + } else if (depth == 0 && c == '=' + && (i + 1 >= args.length() || args.charAt(i + 1) != '=')) { if (word.toString().trim().equals(attr)) { return true; } @@ -2274,4 +2268,42 @@ private static boolean declaresAttribute(String args, String attr) { } return false; } + + /// If a string, character literal or comment starts at `i`, the index just + /// past it; otherwise `i`. + private static int skipNonCode(String s, int i) { + char c = s.charAt(i); + if (c == '"') { + for (int j = i + 1; j < s.length(); j++) { + if (s.charAt(j) == '\\') { + j++; + } else if (s.charAt(j) == '"') { + return j + 1; + } + } + return s.length(); + } + if (c == '\'') { + for (int j = i + 1; j < s.length(); j++) { + if (s.charAt(j) == '\\') { + j++; + } else if (s.charAt(j) == '\'') { + return j + 1; + } + } + return s.length(); + } + if (c == '/' && i + 1 < s.length()) { + char n = s.charAt(i + 1); + if (n == '/') { + int nl = s.indexOf('\n', i); + return nl < 0 ? s.length() : nl; + } + if (n == '*') { + int close = s.indexOf("*/", i + 2); + return close < 0 ? s.length() : close + 2; + } + } + return i; + } } diff --git a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java index f41fbd9eb9a..45f7a3db8e2 100644 --- a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java +++ b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java @@ -195,6 +195,38 @@ public void valuesContainingSeparatorsDoNotCreatePhantomOwnership() { assertTrue(owned.get("android.debug") == null); } + /** + * A comment inside an annotation can carry an unmatched delimiter. Counting + * it as syntax loses the annotation's boundary, and the hint it owns stays + * editable -- so Add writes the duplicate the next build refuses. + */ + @Test + public void commentsInsideAnAnnotationDoNotBreakOwnership() { + String src = "@Ios(/* required for issue ( */ teamId = \"T\")\n" + + "public class MyApp {}\n"; + java.util.Map owned = new java.util.HashMap<>(); + CodenameOneSettings.collectAnnotationOwnedHints(src, owned); + assertEquals("@Ios(teamId)", owned.get("ios.teamId")); + } + + @Test + public void lineCommentsAndCharLiteralsDoNotBreakOwnership() { + String src = "@Ios(\n" + + " // a stray ) in a line comment\n" + + " teamId = \"T\",\n" + + " urlScheme = \"x\")\n" + + "public class MyApp {}\n"; + java.util.Map owned = new java.util.HashMap<>(); + CodenameOneSettings.collectAnnotationOwnedHints(src, owned); + assertEquals("@Ios(teamId)", owned.get("ios.teamId")); + assertEquals("@Ios(urlScheme)", owned.get("ios.urlScheme")); + + String withChar = "@Android(xpermissions = \"a\") // ')'\npublic class MyApp {}\n"; + java.util.Map owned2 = new java.util.HashMap<>(); + CodenameOneSettings.collectAnnotationOwnedHints(withChar, owned2); + assertEquals("@Android(xpermissions)", owned2.get("android.xpermissions")); + } + @Test public void searchStillMatchesOnNameAndDescription() { BuildHintCatalog catalog = BuildHintCatalog.load(); From 8be6d5f661b95a3c688ee3b0c8a22a3a2bcfff9c Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 17:20:22 +0300 Subject: [PATCH 17/23] Refuse a build whose annotations were never processed The P1 is about the feature, not the migration convenience: a mojo's default phase does not add an execution to a project, so an existing application that follows the package documentation and adopts the annotations compiles cleanly and ships with every annotated hint missing. Nothing said so. CN1BuildMojo now checks, when no annotation manifest was found, whether the application classes carry build hint annotations at all -- read out of the class file's annotation table, so it sees what the compiler emitted rather than what the source appears to say. If they do, the build fails with the execution to add. Both a directory and a jar are scanned, because a reactor `package` build hands the dependency module's jar rather than its output directory, which is exactly the shape this has to work in. The package documentation now states the requirement too. Verified on a generated project: with the binding removed and one @Ios on the main class the build refuses; with the binding restored it applies the hint and carries on. Two more from the same review: - Verification accepted a manifest an earlier build had left behind, so with processing now skipped or unbound the check passed against a stale file, the properties were deleted, and the next clean build dropped the hints. The resource is removed before the nested build, so what is checked is what that invocation produced. - The Settings source scan matched only the imported simple name, missing the equally valid `@com.codename1.annotations.buildhints.Ios(...)`. Both spellings are matched now, with the name boundary checked so `@Ios` cannot match `@IosPrivacy`. The boundary test is hand-rolled because Character.isJavaIdentifierPart is outside the API subset this class compiles against -- the bytecode compliance gate caught that. Co-Authored-By: Claude Opus 5 (1M context) --- .../annotations/buildhints/package-info.java | 16 +++ .../build/shared/BuildHintCodeGenerator.java | 16 +++ .../com/codename1/maven/CN1BuildMojo.java | 124 +++++++++++++++++- .../maven/MigrateBuildHintsMojo.java | 11 +- .../settings/CodenameOneSettings.java | 53 ++++++-- .../settings/BuildHintCatalogTest.java | 26 ++++ 6 files changed, 231 insertions(+), 15 deletions(-) diff --git a/CodenameOne/src/com/codename1/annotations/buildhints/package-info.java b/CodenameOne/src/com/codename1/annotations/buildhints/package-info.java index f040888412c..a4c36dbcccf 100644 --- a/CodenameOne/src/com/codename1/annotations/buildhints/package-info.java +++ b/CodenameOne/src/com/codename1/annotations/buildhints/package-info.java @@ -46,6 +46,22 @@ /// continues to work exactly as before. Setting the same hint in both places is /// a build error. /// +/// A project generated recently already runs the goal that turns these into +/// build hints. An older one may not: a goal's default phase does not add an +/// execution to a project, so the annotations would compile and then be +/// ignored. The build refuses rather than shipping without them, and the module +/// that compiles the main class needs: +/// +/// ```xml +/// +/// cn1-process-classes +/// process-classes +/// +/// process-annotations +/// +/// +/// ``` +/// /// Generated from com.codename1.build.shared.BuildHints by /// BuildHintCodeGenerator. Do not edit by hand -- edit the catalog and /// re-run scripts/gen-build-hint-annotations.sh. diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java index 067e2c4c14f..626ec0c9867 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintCodeGenerator.java @@ -376,6 +376,22 @@ private static String packageInfoSource(Map> by + "`codenameone_settings.properties`, which continues to work exactly as " + "before. Setting the same hint in both places is a build error.", "")); sb.append("///\n"); + sb.append(doc("A project generated recently already runs the goal that turns these into " + + "build hints. An older one may not: a goal's default phase does not add an " + + "execution to a project, so the annotations would compile and then be ignored. " + + "The build refuses rather than shipping without them, and the module that " + + "compiles the main class needs:", "")); + sb.append("///\n"); + sb.append("/// ```xml\n"); + sb.append("/// \n"); + sb.append("/// cn1-process-classes\n"); + sb.append("/// process-classes\n"); + sb.append("/// \n"); + sb.append("/// process-annotations\n"); + sb.append("/// \n"); + sb.append("/// \n"); + sb.append("/// ```\n"); + sb.append("///\n"); sb.append(GENERATED_NOTE); sb.append("package ").append(PKG).append(";\n"); return sb.toString(); diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java index 8c01a5432f7..363e4b9adbe 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java @@ -2548,7 +2548,8 @@ private SortedProperties mergeRequiredProperties(String libraryName, Properties * written by the annotation processor on every build and deleted by it when * the last annotation goes away, so it always reflects the current source.

*/ - private void mergeAnnotationBuildHints(Properties target, List classpathElements) { + private void mergeAnnotationBuildHints(Properties target, List classpathElements) + throws MojoFailureException { if (target == null || classpathElements == null) { return; } @@ -2587,6 +2588,127 @@ private void mergeAnnotationBuildHints(Properties target, List classpath return; } } + // Nothing was applied. If the compiled classes carry build hint + // annotations anyway, the processor never ran -- a mojo's defaultPhase + // does not add an execution to a project's POM, so an app that adopts the + // annotations without binding process-annotations compiles cleanly and + // ships with every annotated hint missing. Refuse rather than build that. + String annotated = classCarryingBuildHintAnnotations(classpathElements); + if (annotated != null) { + throw new MojoFailureException(annotated + " carries build hint annotations, but no " + + ANNOTATION_HINTS_RESOURCE + " was produced, so none of them reached this " + + "build.\n\nThe cn1 process-annotations goal has to run on the module that " + + "compiles it:\n" + + " \n" + + " cn1-process-classes\n" + + " process-classes\n" + + " \n" + + " process-annotations\n" + + " \n" + + " "); + } + } + + /** + * The first application class found carrying a build hint annotation, or null. + * + *

Read straight out of the class file's annotation table rather than from + * source, so it sees exactly what the compiler emitted.

+ */ + private String classCarryingBuildHintAnnotations(List classpathElements) { + java.util.Collection descriptors = + com.codename1.build.shared.BuildHintAnnotationBinding.descriptors(); + for (String element : classpathElements) { + File f = new File(element); + if (f.isDirectory()) { + String hit = findAnnotatedClass(f, descriptors); + if (hit != null) { + return hit; + } + continue; + } + // A reactor `package` build hands us the dependency module's jar + // rather than its output directory, which is exactly the shape this + // check has to work in. + if (f.isFile() && f.getName().endsWith(".jar")) { + String hit = findAnnotatedClassInJar(f, descriptors); + if (hit != null) { + return hit; + } + } + } + return null; + } + + private String findAnnotatedClassInJar(File jar, java.util.Collection descriptors) { + try (java.util.zip.ZipFile zip = new java.util.zip.ZipFile(jar)) { + java.util.Enumeration entries = zip.entries(); + while (entries.hasMoreElements()) { + java.util.zip.ZipEntry entry = entries.nextElement(); + if (entry.isDirectory() || !entry.getName().endsWith(".class")) { + continue; + } + try (InputStream in = zip.getInputStream(entry)) { + String name = carriesBuildHintAnnotation(in, descriptors) + ? entry.getName() : null; + if (name != null) { + return name.substring(0, name.length() - ".class".length()) + .replace('/', '.'); + } + } + } + } catch (IOException | RuntimeException ex) { + getLog().debug("cn1: could not scan " + jar + ": " + ex.getMessage()); + } + return null; + } + + private boolean carriesBuildHintAnnotation(InputStream in, + java.util.Collection descriptors) + throws IOException { + final boolean[] seen = {false}; + new org.objectweb.asm.ClassReader(in).accept( + new org.objectweb.asm.ClassVisitor(org.objectweb.asm.Opcodes.ASM9) { + @Override + public org.objectweb.asm.AnnotationVisitor visitAnnotation( + String desc, boolean visible) { + if (descriptors.contains(desc)) { + seen[0] = true; + } + return null; + } + }, + org.objectweb.asm.ClassReader.SKIP_CODE + | org.objectweb.asm.ClassReader.SKIP_DEBUG + | org.objectweb.asm.ClassReader.SKIP_FRAMES); + return seen[0]; + } + + private String findAnnotatedClass(File dir, java.util.Collection descriptors) { + File[] children = dir.listFiles(); + if (children == null) { + return null; + } + for (File f : children) { + if (f.isDirectory()) { + String hit = findAnnotatedClass(f, descriptors); + if (hit != null) { + return hit; + } + continue; + } + if (!f.getName().endsWith(".class")) { + continue; + } + try (InputStream in = new FileInputStream(f)) { + if (carriesBuildHintAnnotation(in, descriptors)) { + return f.getName().substring(0, f.getName().length() - ".class".length()); + } + } catch (IOException | RuntimeException ex) { + getLog().debug("cn1: could not scan " + f + ": " + ex.getMessage()); + } + } + return null; } /** diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index 40bdd1e880f..7dcbc474ec3 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -292,6 +292,16 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException private String verifyAnnotationsAreProcessed(File projectDir, List migratedKeys) { getLog().info("cn1: building " + projectDir.getName() + " to confirm the annotations produce the hints..."); + // Delete any manifest an earlier build left behind first. Checking that + // the file exists and holds the right keys proves nothing if it was + // already there: with processing now skipped or unbound the nested build + // leaves it untouched, the check passes, the properties are deleted, and + // the next clean build removes the stale artifact and the hints with it. + File emitted = new File(projectDir, "target/classes/" + ANNOTATION_HINTS_RESOURCE); + if (emitted.isFile() && !emitted.delete()) { + return "Could not remove the previous " + ANNOTATION_HINTS_RESOURCE + + ", so this build's output could not be told apart from it."; + } File pom = new File(projectDir, "pom.xml"); InvocationRequest request = new DefaultInvocationRequest(); request.setPomFile(pom.isFile() ? pom : new File(project.getBasedir(), "pom.xml")); @@ -311,7 +321,6 @@ private String verifyAnnotationsAreProcessed(File projectDir, List migra + "), so the annotations could not be checked."; } - File emitted = new File(projectDir, "target/classes/" + ANNOTATION_HINTS_RESOURCE); if (!emitted.isFile()) { return "No " + ANNOTATION_HINTS_RESOURCE + " was written under " + projectDir.getName() + "/target/classes."; diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java index 4e5d7405e62..be14fccbed1 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java @@ -2193,20 +2193,38 @@ static void collectAnnotationOwnedHints(String source, java.util.Map= 0) { - int open = source.indexOf('(', at); - if (open < 0) { - break; - } - String args = balancedArgs(source, open); - if (args != null && declaresAttribute(args, h.attr())) { - out.put(com.codename1.build.shared.BuildHints.canonicalName(h.name()), - marker + "(" + h.attr() + ")"); - break; + String simple = h.group().annotationSimpleName(); + // Both spellings are valid: the imported simple name, and the fully + // qualified one, which needs no import. Missing the qualified form + // left the hint editable and Add wrote the duplicate declaration. + String[] markers = { + "@" + simple, + "@com.codename1.annotations.buildhints." + simple, + }; + boolean found = false; + for (int m = 0; m < markers.length && !found; m++) { + int at = source.indexOf(markers[m]); + while (at >= 0) { + // "@Ios" must not match "@IosPrivacy": the next character has + // to end the name. + int after = at + markers[m].length(); + if (after < source.length() && continuesAName(source.charAt(after))) { + at = source.indexOf(markers[m], after); + continue; + } + int open = source.indexOf('(', at); + if (open < 0) { + break; + } + String args = balancedArgs(source, open); + if (args != null && declaresAttribute(args, h.attr())) { + out.put(com.codename1.build.shared.BuildHints.canonicalName(h.name()), + "@" + simple + "(" + h.attr() + ")"); + found = true; + break; + } + at = source.indexOf(markers[m], after); } - at = source.indexOf(marker, at + marker.length()); } } } @@ -2269,6 +2287,15 @@ private static boolean declaresAttribute(String args, String attr) { return false; } + /// Whether `c` could continue a Java identifier. + /// + /// Hand-rolled because Character.isJavaIdentifierPart is outside the + /// Codename One API subset, and this class is compiled as app code. + private static boolean continuesAName(char c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9') || c == '_' || c == '$'; + } + /// If a string, character literal or comment starts at `i`, the index just /// past it; otherwise `i`. private static int skipNonCode(String s, int i) { diff --git a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java index 45f7a3db8e2..8abfb969e3e 100644 --- a/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java +++ b/scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java @@ -227,6 +227,32 @@ public void lineCommentsAndCharLiteralsDoNotBreakOwnership() { assertEquals("@Android(xpermissions)", owned2.get("android.xpermissions")); } + /** + * The fully qualified spelling needs no import and is equally valid. Missing + * it left the hint editable, and Add then wrote the duplicate declaration. + */ + @Test + public void fullyQualifiedAnnotationsAreRecognized() { + String src = "@com.codename1.annotations.buildhints.Ios(teamId = \"T\")\n" + + "public class MyApp {}\n"; + java.util.Map owned = new java.util.HashMap<>(); + CodenameOneSettings.collectAnnotationOwnedHints(src, owned); + assertEquals("@Ios(teamId)", owned.get("ios.teamId")); + } + + /** `@Ios` must not match `@IosPrivacy`, which is a different annotation. */ + @Test + public void aSimpleNameDoesNotMatchALongerAnnotation() { + String src = "@IosPrivacy(cameraUsageDescription = \"why\")\n" + + "public class MyApp {}\n"; + java.util.Map owned = new java.util.HashMap<>(); + CodenameOneSettings.collectAnnotationOwnedHints(src, owned); + assertEquals("@IosPrivacy(cameraUsageDescription)", + owned.get("ios.NSCameraUsageDescription")); + assertTrue(owned.get("ios.teamId") == null, + "@IosPrivacy must not be read as @Ios"); + } + @Test public void searchStillMatchesOnNameAndDescription() { BuildHintCatalog catalog = BuildHintCatalog.load(); From fb5a6c7169c652710839bd4c963868891ab27501 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 18:00:13 +0300 Subject: [PATCH 18/23] Do not refuse a build over an annotation that sets nothing Three from the same review. @Ios() with every member left at its default is legal Java -- it is what is left after the last attribute is deleted -- and the processor emits the manifest for it, stamped with the main class but carrying no hint. The merge judged by the hint count, read that as "the processor never ran", and refused the build until the annotation itself was deleted. The manifest's presence is what proves processing happened, so that is what the check now reads; the refusal still fires for the case it exists for, annotations in the compiled classes with no manifest anywhere. The migration goal restored both files when the verification build failed, but not when the mutation itself did. If the annotations went in and the properties rewrite then failed -- unwritable file, full disk, a partial write -- the project was left declaring the same hint twice, which is exactly the state the next build refuses to compile: worse than not having migrated at all. The restore is one helper now and runs for either failure. A dangling javadoc left over from a removed method went with it. pr.yml ignores scripts/** and re-includes a fixed list, so a PR touching only the catalog gate, its miner, or its baseline started no workflow at all -- the gate could be broken, or its empty baseline relaxed, without ever running. The five files are re-included in both the pull_request and push filters. The merge test needed the annotated class present alongside the empty manifest to trip the refusal at all; without it the test passed against the bug it was written for. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/pr.yml | 18 ++ .../com/codename1/maven/CN1BuildMojo.java | 14 +- .../maven/MigrateBuildHintsMojo.java | 58 +++-- .../maven/AnnotationBuildHintMergeTest.java | 204 ++++++++++++++++++ .../BuildHintAnnotationProcessorTest.java | 15 ++ 5 files changed, 288 insertions(+), 21 deletions(-) create mode 100644 maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index e70275e9810..84eb9531958 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -27,6 +27,15 @@ on: - 'scripts/ci/retry.sh' - 'scripts/ci/apt-get-update.sh' - 'scripts/ci/apt-get-install.sh' + # The build hint gates are run from this workflow and nowhere else, and one + # of them holds an empty baseline. Ignoring the whole directory meant a + # change that breaks a gate, or that adds a line to the baseline, could + # merge without the gate it weakens ever running. + - 'scripts/check-build-hint-catalog.sh' + - 'scripts/check-build-hint-catalog.py' + - 'scripts/build_hint_miner.py' + - 'scripts/build-hint-catalog-baseline.txt' + - 'scripts/gen-build-hint-annotations.sh' - '!docs/**' - '!**/*.md' - '!.github/workflows/developer-guide-docs.yml' @@ -59,6 +68,15 @@ on: - 'scripts/ci/retry.sh' - 'scripts/ci/apt-get-update.sh' - 'scripts/ci/apt-get-install.sh' + # The build hint gates are run from this workflow and nowhere else, and one + # of them holds an empty baseline. Ignoring the whole directory meant a + # change that breaks a gate, or that adds a line to the baseline, could + # merge without the gate it weakens ever running. + - 'scripts/check-build-hint-catalog.sh' + - 'scripts/check-build-hint-catalog.py' + - 'scripts/build_hint_miner.py' + - 'scripts/build-hint-catalog-baseline.txt' + - 'scripts/gen-build-hint-annotations.sh' - '!docs/**' - '!**/*.md' - '!.github/workflows/developer-guide-docs.yml' diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java index 363e4b9adbe..562e03a27d1 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java @@ -2562,6 +2562,13 @@ private void mergeAnnotationBuildHints(Properties target, List classpath ? main.trim() : pkg.trim() + "." + main.trim(); } } + // The manifest's presence, not its contents, is what proves the processor + // ran. An annotation with every member left at its default -- @Ios() after + // the last attribute was deleted -- is legal Java, and the processor emits + // a manifest carrying only the main-class stamp for it. Judging by the hint + // count alone would read that as "never processed" and refuse a build that + // is in fact perfectly configured. + boolean processed = false; for (String element : classpathElements) { Properties found = readAnnotationHints(new File(element)); if (found == null) { @@ -2575,6 +2582,7 @@ private void mergeAnnotationBuildHints(Properties target, List classpath + " -- they were generated for " + stamped); continue; } + processed = true; int applied = 0; for (String key : found.stringPropertyNames()) { if (!key.startsWith("codename1.arg.")) { @@ -2588,7 +2596,11 @@ private void mergeAnnotationBuildHints(Properties target, List classpath return; } } - // Nothing was applied. If the compiled classes carry build hint + if (processed) { + getLog().debug("cn1: annotations were processed and set no build hint"); + return; + } + // No manifest at all. If the compiled classes carry build hint // annotations anyway, the processor never ran -- a mojo's defaultPhase // does not add an execution to a project's POM, so an app that adopts the // annotations without binding process-annotations compiles cleanly and diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index 7dcbc474ec3..005d258d59f 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -232,28 +232,30 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException try { originalSource = read(source); originalSettings = readProperties(settingsFile); + } catch (IOException ex) { + throw new MojoExecutionException("Migration failed: " + ex.getMessage(), ex); + } + + // Anything that throws from here on has to put both files back. The half + // that fails is not always the second one: if the annotations go in and + // the properties rewrite then fails -- an unwritable file, a full disk, a + // partial write -- the project is left declaring the same hint twice, + // which is exactly the state the next build refuses to compile. Leaving + // the developer with that is worse than not migrating at all. + try { insertAnnotations(source, rendered.toString(), settings.getProperty("codename1.mainName", "").trim()); removeMigratedLines(settingsFile, migratedKeys); - } catch (IOException ex) { - throw new MojoExecutionException("Migration failed: " + ex.getMessage(), ex); + } catch (IOException | RuntimeException ex) { + throw new MojoExecutionException("Migration failed, so " + source.getName() + " and " + + settingsFile.getName() + " have been put back as they were: " + + ex.getMessage() + + restore(source, originalSource, settingsFile, originalSettings), ex); } String missing = verifyAnnotationsAreProcessed(projectDir, migratedKeys); if (missing != null) { - StringBuilder restoreFailed = new StringBuilder(); - try { - write(source, originalSource); - } catch (IOException ex) { - restoreFailed.append("\nCould not restore ").append(source).append(": ") - .append(ex.getMessage()); - } - try { - writeProperties(settingsFile, originalSettings); - } catch (IOException ex) { - restoreFailed.append("\nCould not restore ").append(settingsFile).append(": ") - .append(ex.getMessage()); - } + String restoreFailed = restore(source, originalSource, settingsFile, originalSettings); throw new MojoFailureException("The annotations were added but the build did not turn " + "them into build hints, so " + source.getName() + " and " + settingsFile.getName() + " have been put back as they were.\n\n" @@ -275,13 +277,29 @@ protected void executeImpl() throws MojoExecutionException, MojoFailureException } /** - * Whether any module in the reactor binds the {@code process-annotations} - * goal. + * Puts both files back as they were. * - *

Checked across the reactor rather than on {@code project} because this - * goal is an aggregator, so {@code project} is the root POM while the binding - * lives in the common module.

+ * @return an empty string when both were restored, otherwise a description of + * what could not be, to append to the failure being reported */ + private String restore(File source, String originalSource, + File settingsFile, String originalSettings) { + StringBuilder failed = new StringBuilder(); + try { + write(source, originalSource); + } catch (IOException ex) { + failed.append("\nCould not restore ").append(source).append(": ") + .append(ex.getMessage()); + } + try { + writeProperties(settingsFile, originalSettings); + } catch (IOException ex) { + failed.append("\nCould not restore ").append(settingsFile).append(": ") + .append(ex.getMessage()); + } + return failed.toString(); + } + /** * Runs the project's own build over the module that holds the main class and * checks that every migrated hint came back out of it. diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java new file mode 100644 index 00000000000..7c32c5f3dc2 --- /dev/null +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ +package com.codename1.maven; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * Where the hints that came from annotations meet the build request. + * + *

The merge has to distinguish three states that look alike from here: the + * processor ran and produced hints, it ran and produced none, and it never ran + * at all. Only the third is a broken build, and getting that wrong either ships + * an app with its build configuration silently missing or refuses one that is + * perfectly configured.

+ */ +public class AnnotationBuildHintMergeTest { + + @Rule + public TemporaryFolder tmp = new TemporaryFolder(); + + private static final String RESOURCE = "META-INF/codenameone/build-hints.properties"; + + @Test + public void hintsFromTheManifestReachTheBuildRequest() throws Exception { + File classes = manifest("cn1.buildHints.mainClass=com.example.MyApp\n" + + "codename1.arg.ios.pods=Alamofire\n"); + Properties target = new Properties(); + + merge(target, classes, "MyApp", "com.example"); + + assertEquals("Alamofire", target.getProperty("codename1.arg.ios.pods")); + } + + /** + * A manifest with no hints in it is what {@code @Ios()} produces once the + * last attribute is deleted -- still legal, still processed. Judging by the + * hint count alone read that as "the processor never ran" and refused every + * build until the annotation itself was removed. + */ + @Test + public void anEmptyManifestIsProofTheProcessorRan() throws Exception { + File classes = manifest("cn1.buildHints.mainClass=com.example.MyApp\n"); + // The annotated class has to be there too -- that is the whole situation: + // an annotation the compiler recorded and a manifest that carries no hint + // for it. Without the class the refusal path has nothing to trip on and + // the test would pass against the bug it exists for. + writeAnnotatedClass(classes); + Properties target = new Properties(); + + merge(target, classes, "MyApp", "com.example"); + + assertTrue("no hint should have been applied", target.isEmpty()); + } + + /** + * The refusal still has to fire for the case it exists for: annotations in + * the compiled classes with no manifest anywhere means the goal is unbound, + * and every annotated hint is missing from the build. + */ + @Test + public void annotatedClassesWithNoManifestAreRefused() throws Exception { + File classes = tmp.newFolder(); + writeAnnotatedClass(classes); + try { + merge(new Properties(), classes, "MyApp", "com.example"); + fail("expected the build to be refused"); + } catch (InvocationTargetException ex) { + assertTrue(String.valueOf(ex.getCause().getMessage()), + ex.getCause().getMessage().contains("process-annotations")); + } + } + + /** No annotations and no manifest is an ordinary properties-file project. */ + @Test + public void aProjectWithNoAnnotationsIsLeftAlone() throws Exception { + Properties target = new Properties(); + merge(target, tmp.newFolder(), "MyApp", "com.example"); + assertTrue(target.isEmpty()); + } + + /** A manifest stamped for another project is somebody else's configuration. */ + @Test + public void aManifestStampedForAnotherMainClassIsIgnored() throws Exception { + File classes = manifest("cn1.buildHints.mainClass=com.other.TheirApp\n" + + "codename1.arg.ios.pods=Alamofire\n"); + Properties target = new Properties(); + + merge(target, classes, "MyApp", "com.example"); + + assertNull(target.getProperty("codename1.arg.ios.pods")); + } + + // ------------------------------------------------------------------ + // helpers + // ------------------------------------------------------------------ + + private File manifest(String body) throws Exception { + File classes = tmp.newFolder(); + File out = new File(classes, RESOURCE); + out.getParentFile().mkdirs(); + try (Writer w = new OutputStreamWriter(new FileOutputStream(out), "ISO-8859-1")) { + w.write(body); + } + return classes; + } + + /** Compiles a main class carrying one build hint annotation. */ + private void writeAnnotatedClass(File classes) throws Exception { + com.codename1.maven.annotations.JavaSourceCompiler.compile( + com.codename1.maven.annotations.JavaSourceCompiler.singleSource( + "com.example.MyApp", + "package com.example;\n" + + "import com.codename1.annotations.buildhints.Ios;\n" + + "@Ios(teamId = \"ABCDE12345\")\n" + + "public class MyApp {\n}\n"), + classes, + Arrays.asList(new File(Class.forName("com.codename1.annotations.buildhints.Ios") + .getProtectionDomain().getCodeSource().getLocation().toURI()))); + } + + /** + * Drives the shipped merge rather than a restatement of it, so a change to + * the rule is a change to what this asserts. + */ + private void merge(Properties target, File classesDir, String mainName, String pkg) + throws Exception { + CN1BuildMojo mojo = new CN1BuildMojo(); + + Properties settings = new Properties(); + settings.setProperty("codename1.mainName", mainName); + settings.setProperty("codename1.packageName", pkg); + Field props = findField(mojo.getClass(), "properties"); + props.setAccessible(true); + props.set(mojo, settings); + + List cp = Collections.singletonList(classesDir.getAbsolutePath()); + Method m = findMethod(mojo.getClass(), "mergeAnnotationBuildHints", + Properties.class, List.class); + m.setAccessible(true); + m.invoke(mojo, target, cp); + } + + private static Field findField(Class type, String name) throws NoSuchFieldException { + for (Class c = type; c != null; c = c.getSuperclass()) { + try { + return c.getDeclaredField(name); + } catch (NoSuchFieldException keepLooking) { + // up the chain + } + } + throw new NoSuchFieldException(name); + } + + private static Method findMethod(Class type, String name, Class... args) + throws NoSuchMethodException { + for (Class c = type; c != null; c = c.getSuperclass()) { + try { + return c.getDeclaredMethod(name, args); + } catch (NoSuchMethodException keepLooking) { + // up the chain + } + } + throw new NoSuchMethodException(name); + } +} diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java index 8ea6d65479e..b7fe0094f31 100644 --- a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/processors/BuildHintAnnotationProcessorTest.java @@ -262,6 +262,21 @@ public void aCommentedOutPropertyIsNotAConflict() throws Exception { assertFalse(ctx.hasErrors()); } + /// An annotation with every member left at its default is legal Java, and + /// `@Ios()` is what is left after the last attribute is deleted. The manifest + /// is still emitted for it, carrying only the main-class stamp: its presence + /// is what tells the build that processing ran at all, and dropping it here + /// would make a harmless annotation indistinguishable from an unbound goal. + @Test + public void anAnnotationWithNoMembersStillEmitsAStampedManifest() throws Exception { + Properties p = hintsOf("@Ios()"); + assertEquals(MAIN, p.getProperty("cn1.buildHints.mainClass")); + for (String key : p.stringPropertyNames()) { + assertFalse("no hint should have been written, got " + key, + key.startsWith("codename1.arg.")); + } + } + // ------------------------------------------------------------------ // helpers // ------------------------------------------------------------------ From 51fb76af1588bc640b36ea3b6d942b8f2fb46822 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 18:56:29 +0300 Subject: [PATCH 19/23] Tell a current annotation manifest from last build's MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three from the same review, all cases where something looked applied and was not. The main-class stamp says which class produced the manifest, not when. Nothing clears target/classes between builds, so a project that ran process-annotations once and then stopped -- goal unbound, skipped, moved to a phase that no longer runs -- keeps a manifest naming the right class while the annotations beside it change. The merge accepted it, applied the older values, and the guard added for exactly this never fired. The processor now records a fingerprint of the annotations it read, taken over the raw members rather than the hints they convert into so it moves for anything the developer can change: a different value, an added or removed attribute, a whole annotation gained or lost. The merge recomputes it from the main class on the classpath -- directory or jar -- and refuses a manifest that does not match, naming it as left over from an earlier build. It refuses only on positive evidence: no main class name, no class file, no recorded fingerprint, or an unreadable one, and the manifest is taken at face value as before. A hint set by @Hardening reached the settings only in createAntProject, which runs after the early hardening pre-flight and after hardeningCacheKey is read for the Android up-to-date check. The early pass computed "unhardened" from the properties file while the finished build recorded "hardened:...", so the keys never matched and an up-to-date APK was rebuilt on every invocation. Worse, an unsupported hardening request made through an annotation escaped the refusal that pass exists to perform. Annotation hints are merged there too, before the -D overlay so a command-line hint still wins. Properties.load turns € in the settings file into a real euro sign, and migrate-build-hints writes the source back through ISO-8859-1 to keep the untouched part byte-identical -- so emitting the character raw wrote '?' for anything unmappable and a high byte for anything else, corrupting a UTF-8 source. The verification build would not have noticed: it checks that the hint came back, not what its value was. Non-ASCII is written as \uXXXX, which Java and Kotlin both accept, and a backslash before one still survives -- Java recognises a unicode escape only after an even number of backslashes, so there is a test pinning that rather than leaving it to luck. Co-Authored-By: Claude Opus 5 (1M context) --- .../com/codename1/maven/CN1BuildMojo.java | 96 ++++++++++++++++++- .../maven/MigrateBuildHintsMojo.java | 19 +++- .../BuildHintAnnotationProcessor.java | 87 +++++++++++++++++ .../maven/AnnotationBuildHintMergeTest.java | 75 +++++++++++++++ .../MigrateBuildHintsPropertyParsingTest.java | 29 ++++++ 5 files changed, 303 insertions(+), 3 deletions(-) diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java index 562e03a27d1..9511736a5c6 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java @@ -321,10 +321,22 @@ private void applyHardeningPreflight() throws MojoFailureException { getLog().debug("Could not read codenameone_settings.properties for hardening pre-flight", ex); } } + // A hint set by @Hardening reaches the settings only in createAntProject, which runs after + // the Android up-to-date short-circuit below and after hardeningCacheKey is read from it. + // Without this the early pass computes "unhardened" from the file while the completed build + // records "hardened:...", the two never match, and an up-to-date APK is rebuilt on every + // invocation -- and, worse, an unsupported hardening request made through an annotation + // escapes the refusal this early pass exists to perform. + try { + mergeAnnotationBuildHints(settings, project.getCompileClasspathElements()); + } catch (org.apache.maven.artifact.DependencyResolutionRequiredException ex) { + getLog().debug("Could not read annotation build hints for the hardening pre-flight", ex); + } // Overlay -D command-line hints (e.g. -Dcodename1.arg.harden.level=standard) so an explicit // hardening request made only on the command line is seen by this early check -- and, because this // runs before the Android up-to-date cache short-circuit, is not silently dropped when a prior APK // is newer than the sources (getSourcesModificationTime does not account for build hints). + // After the annotations, so -D still wins over one. overlayCommandLineBuildHints(settings); applyHardeningPreflight(settings); } @@ -2569,6 +2581,7 @@ private void mergeAnnotationBuildHints(Properties target, List classpath // count alone would read that as "never processed" and refuse a build that // is in fact perfectly configured. boolean processed = false; + String stale = null; for (String element : classpathElements) { Properties found = readAnnotationHints(new File(element)); if (found == null) { @@ -2582,6 +2595,20 @@ private void mergeAnnotationBuildHints(Properties target, List classpath + " -- they were generated for " + stamped); continue; } + // The stamp says which class produced this file, not when. Nothing + // clears target/classes between builds, so a project that ran the + // processor once and then stopped -- goal unbound, skipped, or bound + // to a phase that no longer runs -- keeps a manifest naming the right + // class while the annotations beside it have changed. Comparing the + // recorded fingerprint against the compiled class is what tells those + // apart; without it the build silently ships the older values and the + // guard below never runs. + String mismatch = digestMismatch(new File(element), expectedMain, found); + if (mismatch != null) { + getLog().debug("cn1: ignoring build hints from " + element + " -- " + mismatch); + stale = mismatch; + continue; + } processed = true; int applied = 0; for (String key : found.stringPropertyNames()) { @@ -2607,8 +2634,12 @@ private void mergeAnnotationBuildHints(Properties target, List classpath // ships with every annotated hint missing. Refuse rather than build that. String annotated = classCarryingBuildHintAnnotations(classpathElements); if (annotated != null) { - throw new MojoFailureException(annotated + " carries build hint annotations, but no " - + ANNOTATION_HINTS_RESOURCE + " was produced, so none of them reached this " + throw new MojoFailureException(annotated + " carries build hint annotations, but " + + (stale == null + ? "no " + ANNOTATION_HINTS_RESOURCE + " was produced" + : "the only " + ANNOTATION_HINTS_RESOURCE + " on the classpath is left " + + "over from an earlier build (" + stale + ")") + + ", so none of them reached this " + "build.\n\nThe cn1 process-annotations goal has to run on the module that " + "compiles it:\n" + " \n" @@ -2621,6 +2652,67 @@ private void mergeAnnotationBuildHints(Properties target, List classpath } } + /** + * Why a manifest cannot have come from the class beside it, or null when it can. + * + *

Answered only when both halves are actually available: with no + * {@code codename1.mainName}, no class file for it in this classpath element, + * or no recorded fingerprint, there is nothing to compare and the manifest is + * taken at face value -- the same as before this check existed. It refuses + * only on positive evidence of a mismatch.

+ */ + private String digestMismatch(File element, String expectedMain, Properties manifest) { + String recorded = manifest.getProperty( + com.codename1.maven.processors.BuildHintAnnotationProcessor.SOURCE_DIGEST_KEY); + if (expectedMain == null || recorded == null || recorded.length() == 0) { + return null; + } + try { + com.codename1.maven.annotations.AnnotatedClass cls = readClass(element, expectedMain); + if (cls == null) { + return null; + } + String actual = com.codename1.maven.processors.BuildHintAnnotationProcessor + .sourceDigest(cls); + if (recorded.equals(actual)) { + return null; + } + return "it was generated from a different set of annotations on " + + expectedMain + " than the one compiled into " + element; + } catch (IOException | com.codename1.maven.annotations.ProcessingException ex) { + // Unreadable is not evidence of staleness. + getLog().debug("cn1: could not fingerprint " + expectedMain + " in " + element, ex); + return null; + } + } + + /** Reads one compiled class out of a classpath directory or jar. */ + private com.codename1.maven.annotations.AnnotatedClass readClass(File element, String binaryName) + throws IOException, com.codename1.maven.annotations.ProcessingException { + String path = binaryName.replace('.', '/') + ".class"; + if (element.isDirectory()) { + File f = new File(element, path.replace('/', File.separatorChar)); + if (!f.isFile()) { + return null; + } + try (InputStream in = new FileInputStream(f)) { + return com.codename1.maven.annotations.ClassScanner.readClass(in, f); + } + } + if (element.isFile() && element.getName().endsWith(".jar")) { + try (java.util.zip.ZipFile zip = new java.util.zip.ZipFile(element)) { + java.util.zip.ZipEntry entry = zip.getEntry(path); + if (entry == null) { + return null; + } + try (InputStream in = zip.getInputStream(entry)) { + return com.codename1.maven.annotations.ClassScanner.readClass(in, element); + } + } + } + return null; + } + /** * The first application class found carrying a build hint annotation, or null. * diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index 005d258d59f..f5dfd75555b 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -484,6 +484,15 @@ static String enumConstant(String wire) { * {@code implementation "com.x:y:${'$'}{version}"} would either fail to * compile as an unresolved reference or silently resolve to something else. * Java has no such construct, so the escape is emitted only for Kotlin.

+ * + *

Everything outside ASCII is written as a {@code \}{@code uXXXX} escape, + * which both languages accept. {@code Properties.load} turns a + * {@code \}{@code u20ac} in the file into a real euro sign, and the source is + * written back through ISO-8859-1 to keep the rest of the file byte-identical + * -- so emitting the character raw would replace it with {@code ?}, or write a + * high byte that corrupts a UTF-8 source. Neither shows up in the + * verification build, which checks that the hint came back, not what its + * value was.

*/ static String quoteFor(String s, boolean kotlin) { StringBuilder sb = new StringBuilder("\""); @@ -498,7 +507,15 @@ static String quoteFor(String s, boolean kotlin) { case '$': sb.append(kotlin ? "\\$" : "$"); break; - default: sb.append(c); + default: + if (c < 0x20 || c > 0x7e) { + sb.append("\\u"); + for (int shift = 12; shift >= 0; shift -= 4) { + sb.append(Character.forDigit((c >> shift) & 0xf, 16)); + } + } else { + sb.append(c); + } } } return sb.append('"').toString(); diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/processors/BuildHintAnnotationProcessor.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/processors/BuildHintAnnotationProcessor.java index 83bf3482f59..b1d48c568b1 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/processors/BuildHintAnnotationProcessor.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/processors/BuildHintAnnotationProcessor.java @@ -72,6 +72,18 @@ public class BuildHintAnnotationProcessor extends AbstractAnnotationProcessor { /// foreign copy on the classpath can be recognised rather than merged. private static final String MAIN_CLASS_KEY = "cn1.buildHints.mainClass"; + /// Digest of the annotations this file was generated from. + /// + /// The main-class stamp only says *which* class produced it, which is the + /// same class an out-of-date copy names. Nothing removes `target/classes` + /// between builds, so a project that ran this processor once and then stopped + /// -- the goal unbound, skipped, or bound to a phase that no longer runs -- + /// keeps a manifest that looks entirely valid while the annotations beside it + /// have moved on. Recording what it was built from lets the consumer compare + /// it against the class file actually on the classpath and refuse instead of + /// shipping last week's configuration. + public static final String SOURCE_DIGEST_KEY = "cn1.buildHints.sourceDigest"; + /// hint name to value, sorted so the emitted bytes are stable. private final Map hints = new TreeMap(); /// hint name to "@Ios(pods)". @@ -358,6 +370,79 @@ private String wireValue(AnnotatedClass cls, String descriptor, String member, O /// Not `Properties.store`: it writes a timestamp comment, so the bytes would /// differ on every build. That churns the resource in every incremental /// build and defeats the staged-jar staleness comparison in `CN1BuildMojo`. + /// A stable fingerprint of every build hint annotation on `cls`. + /// + /// Taken over the raw annotation members rather than over the hints they + /// convert into, so it changes for anything the developer can change: a + /// different value, an added or removed attribute, a whole annotation + /// gained or lost. Two builds of the same source produce the same string; + /// there is no timestamp or path in it. + public static String sourceDigest(AnnotatedClass cls) throws ProcessingException { + StringBuilder sb = new StringBuilder(); + Set known = new HashSet(BuildHintAnnotationBinding.descriptors()); + // Sorted, because the class file's annotation order is the source's and a + // reordering is not a change. + for (String descriptor : new TreeMap( + cls.getClassAnnotations()).keySet()) { + if (!known.contains(descriptor)) { + continue; + } + sb.append(descriptor).append('{'); + AnnotationValues values = cls.getClassAnnotation(descriptor); + for (Map.Entry e + : new TreeMap(values.all()).entrySet()) { + sb.append(e.getKey()).append('='); + renderForDigest(e.getValue(), sb); + sb.append(';'); + } + sb.append('}'); + } + try { + java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-256"); + byte[] digest = md.digest(sb.toString().getBytes("UTF-8")); + StringBuilder hex = new StringBuilder(); + for (byte b : digest) { + hex.append(Character.forDigit((b >> 4) & 0xf, 16)); + hex.append(Character.forDigit(b & 0xf, 16)); + } + return hex.toString(); + } catch (java.security.NoSuchAlgorithmException | UnsupportedEncodingException ex) { + throw new ProcessingException("Could not fingerprint the build hint annotations", ex); + } + } + + /// The type is part of the rendering, so an int 1 and the string "1" -- which + /// print alike but are different annotations -- do not fingerprint alike. + private static void renderForDigest(Object value, StringBuilder sb) { + if (value == null) { + sb.append("null"); + } else if (value instanceof String[]) { + // How ASM delivers an enum member: {descriptor, CONSTANT_NAME}. + String[] e = (String[]) value; + sb.append("enum:").append(e.length > 0 ? e[0] : "") + .append('.').append(e.length > 1 ? e[1] : ""); + } else if (value instanceof List) { + sb.append('['); + for (Object item : (List) value) { + renderForDigest(item, sb); + sb.append(','); + } + sb.append(']'); + } else if (value instanceof AnnotationValues) { + AnnotationValues nested = (AnnotationValues) value; + sb.append(nested.getDescriptor()).append('{'); + for (Map.Entry e + : new TreeMap(nested.all()).entrySet()) { + sb.append(e.getKey()).append('='); + renderForDigest(e.getValue(), sb); + sb.append(';'); + } + sb.append('}'); + } else { + sb.append(value.getClass().getName()).append(':').append(value); + } + } + private byte[] serialize(ProcessorContext ctx) throws ProcessingException { StringBuilder sb = new StringBuilder(); sb.append("# Generated from build hint annotations by the Codename One Maven plugin.\n"); @@ -366,6 +451,8 @@ private byte[] serialize(ProcessorContext ctx) throws ProcessingException { if (main != null) { sb.append(MAIN_CLASS_KEY).append('=').append(escape(main)).append('\n'); } + sb.append(SOURCE_DIGEST_KEY).append('=') + .append(sourceDigest(annotated.get(0))).append('\n'); for (Map.Entry e : hints.entrySet()) { sb.append(escape(BuildHints.ARG_PREFIX + e.getKey())).append('=') .append(escape(e.getValue())).append('\n'); diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java index 7c32c5f3dc2..c84d5571ba2 100644 --- a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java @@ -129,6 +129,63 @@ public void aManifestStampedForAnotherMainClassIsIgnored() throws Exception { assertNull(target.getProperty("codename1.arg.ios.pods")); } + /** + * The processor ran once and then stopped -- goal unbound, skipped, or moved + * to a phase that no longer runs -- and the annotation changed afterwards. + * Nothing clears {@code target/classes}, so the old manifest is still there, + * still naming the right main class. Trusting it ships the previous values + * and hides the fact that the goal is not running at all. + */ + @Test + public void aManifestThatDoesNotMatchTheCompiledAnnotationsIsRefused() throws Exception { + File classes = manifest("cn1.buildHints.mainClass=com.example.MyApp\n" + + "cn1.buildHints.sourceDigest=" + digestOf("@Ios(teamId = \"OLD\")") + "\n" + + "codename1.arg.ios.teamId=OLD\n"); + writeAnnotatedClass(classes); // compiled with teamId = ABCDE12345 + + Properties target = new Properties(); + try { + merge(target, classes, "MyApp", "com.example"); + fail("expected the stale manifest to be refused"); + } catch (InvocationTargetException ex) { + assertTrue(String.valueOf(ex.getCause().getMessage()), + ex.getCause().getMessage().contains("left over from an earlier build")); + } + assertNull("the stale value must not have been applied", + target.getProperty("codename1.arg.ios.teamId")); + } + + /** The fingerprint of the annotations the build actually compiled matches. */ + @Test + public void aManifestGeneratedFromTheCompiledAnnotationsIsAccepted() throws Exception { + File classes = manifest("cn1.buildHints.mainClass=com.example.MyApp\n" + + "cn1.buildHints.sourceDigest=" + + digestOf("@Ios(teamId = \"ABCDE12345\")") + "\n" + + "codename1.arg.ios.teamId=ABCDE12345\n"); + writeAnnotatedClass(classes); + + Properties target = new Properties(); + merge(target, classes, "MyApp", "com.example"); + + assertEquals("ABCDE12345", target.getProperty("codename1.arg.ios.teamId")); + } + + /** + * A manifest with no fingerprint in it cannot be judged, so it is taken at + * face value rather than refused on a guess. + */ + @Test + public void aManifestWithNoFingerprintIsStillTrusted() throws Exception { + File classes = manifest("cn1.buildHints.mainClass=com.example.MyApp\n" + + "codename1.arg.ios.teamId=OLD\n"); + writeAnnotatedClass(classes); + + Properties target = new Properties(); + merge(target, classes, "MyApp", "com.example"); + + assertEquals("OLD", target.getProperty("codename1.arg.ios.teamId")); + } + // ------------------------------------------------------------------ // helpers // ------------------------------------------------------------------ @@ -201,4 +258,22 @@ private static Method findMethod(Class type, String name, Class... args) } throw new NoSuchMethodException(name); } + + /** The fingerprint the processor would record for a main class annotated so. */ + private String digestOf(String annotations) throws Exception { + File dir = tmp.newFolder(); + com.codename1.maven.annotations.JavaSourceCompiler.compile( + com.codename1.maven.annotations.JavaSourceCompiler.singleSource( + "com.example.MyApp", + "package com.example;\n" + + "import com.codename1.annotations.buildhints.*;\n" + + annotations + "\n" + + "public class MyApp {\n}\n"), + dir, + Arrays.asList(new File(Class.forName("com.codename1.annotations.buildhints.Ios") + .getProtectionDomain().getCodeSource().getLocation().toURI()))); + return com.codename1.maven.processors.BuildHintAnnotationProcessor.sourceDigest( + com.codename1.maven.annotations.ClassScanner.readClass( + new File(dir, "com/example/MyApp.class"))); + } } diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java index 159ebd3a080..65d72fdbd9f 100644 --- a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java @@ -110,4 +110,33 @@ public void aDefaultPackageSourceStillGetsAUsableAnchor() { public void aValueOnlyLineHasNoSeparator() { assertEquals("bare", MigrateBuildHintsMojo.propertyKeyOf("bare")); } + + /// `Properties.load` turns a `\\u20ac` in the settings file into a real euro + /// sign, and the migrated source is written back through ISO-8859-1 to keep + /// the untouched part of the file byte-identical. Emitting the character raw + /// would write `?` for anything ISO-8859-1 cannot map, and a high byte for + /// anything it can -- which corrupts a UTF-8 source. The verification build + /// would not notice: it checks that the hint came back, not its value. + @Test + public void aNonAsciiCharacterIsWrittenAsAnAsciiEscape() { + assertEquals("\"a\\u20acb\"", MigrateBuildHintsMojo.quoteFor("a\u20acb", false)); + assertEquals("\"a\\u20acb\"", MigrateBuildHintsMojo.quoteFor("a\u20acb", true)); + // Latin-1 is mappable and still escaped: the source may well be UTF-8. + assertEquals("\"caf\\u00e9\"", MigrateBuildHintsMojo.quoteFor("caf\u00e9", false)); + } + + /// A backslash before an escaped character has to stay a backslash. In Java a + /// unicode escape is recognised before parsing and only after an even number + /// of backslashes, so the doubled pair plus our own opener is what makes this + /// come out right rather than a coincidence. + @Test + public void aBackslashBeforeAnEscapedCharacterSurvives() { + assertEquals("\"\\\\\\u00e9\"", MigrateBuildHintsMojo.quoteFor("\\\u00e9", false)); + } + + /// Control characters without a short escape would otherwise go in raw. + @Test + public void aControlCharacterIsEscaped() { + assertEquals("\"\\u0001\"", MigrateBuildHintsMojo.quoteFor("\u0001", false)); + } } From 9c5a58622dc6c578f915b77577856df2bd4b5331 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 22:52:04 +0300 Subject: [PATCH 20/23] Give the same answer whether or not target/classes was cleaned The fingerprint added last round covers the annotations and nothing else, so editing codenameone_settings.properties cannot invalidate it. With processing skipped or unbound, a line added for a hint an annotation already sets left a manifest that still matched -- and the merge quietly replaced the value the developer had just written. The next clean build regenerated the manifest, the processor saw both declarations, and the build failed. Same source, two different outcomes, decided by whether target/classes happened to be cleaned. The merge now refuses a hint the properties file also declares instead of overlaying it, with the message the processor would have given. Aliases count as the same setting, so and.captureRecord in the file still collides with @Android(captureRecord). This is a safety net rather than the primary check: when the processor runs it has already failed for the same reason and can point at the offending line. It only matters in the builds the processor never saw, which are exactly the ones that were silently wrong. Co-Authored-By: Claude Opus 5 (1M context) --- .../com/codename1/maven/CN1BuildMojo.java | 54 +++++++++++++++++++ .../maven/AnnotationBuildHintMergeTest.java | 48 +++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java index 9511736a5c6..5f9c8828289 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java @@ -2615,6 +2615,19 @@ private void mergeAnnotationBuildHints(Properties target, List classpath if (!key.startsWith("codename1.arg.")) { continue; } + // The processor refuses a hint declared as an annotation and as a + // properties line, but it can only refuse the builds it runs in. + // The fingerprint above covers the annotations and nothing else, + // so with processing skipped a line added to the properties file + // afterwards leaves a manifest that still matches -- and this + // overlay would quietly replace the value the developer just + // wrote, until the next clean build regenerated the manifest and + // failed. Same declaration, same answer, whether or not + // target/classes happened to be cleaned. + String conflict = conflictingPropertiesDeclaration(target, key, found); + if (conflict != null) { + throw new MojoFailureException(conflict); + } target.setProperty(key, found.getProperty(key)); applied++; } @@ -2652,6 +2665,47 @@ private void mergeAnnotationBuildHints(Properties target, List classpath } } + /** + * The duplicate-declaration message for a hint set by an annotation and by a + * properties line, or null when there is no clash. + * + *

Only reached when the processor did not run this build; when it did, it + * has already failed for the same reason and with more to say -- it can point + * at the offending line. An alias counts as the same setting, matching what + * the processor checks, so declaring {@code and.captureRecord} in the file + * still collides with {@code @Android(captureRecord)}.

+ */ + private String conflictingPropertiesDeclaration(Properties settings, String key, + Properties manifest) { + String name = key.substring("codename1.arg.".length()); + java.util.Set names = new java.util.LinkedHashSet(); + names.add(name); + for (com.codename1.build.shared.BuildHints.Hint h + : com.codename1.build.shared.BuildHints.entries()) { + if (name.equals(h.aliasOf()) + || name.equals(com.codename1.build.shared.BuildHints.canonicalName(h.name()))) { + names.add(h.name()); + } + } + for (String candidate : names) { + String candidateKey = "codename1.arg." + candidate; + String fromFile = settings.getProperty(candidateKey); + if (fromFile == null) { + continue; + } + String origin = manifest.getProperty("cn1.buildHints.origin." + name); + return candidateKey + " is declared twice.\n" + + " annotation : " + (origin == null ? "on the main class" : origin) + + " = " + manifest.getProperty(key) + "\n" + + " properties : codenameone_settings.properties\n" + + " " + candidateKey + "=" + fromFile + "\n" + + " A build hint has one source of truth. Delete the properties line and " + + "keep the annotation, or delete the annotation attribute and keep the line. " + + "(-D" + candidateKey + "=... overrides either and is not a conflict.)"; + } + return null; + } + /** * Why a manifest cannot have come from the class beside it, or null when it can. * diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java index c84d5571ba2..4f642fe1ba1 100644 --- a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/AnnotationBuildHintMergeTest.java @@ -186,6 +186,54 @@ public void aManifestWithNoFingerprintIsStillTrusted() throws Exception { assertEquals("OLD", target.getProperty("codename1.arg.ios.teamId")); } + /** + * The fingerprint covers the annotations and nothing else, so editing the + * properties file cannot invalidate it. With processing skipped, a line added + * for a hint an annotation already sets left a manifest that still matched -- + * and the overlay quietly replaced the value the developer had just written, + * until the next clean build regenerated the manifest and failed instead. + */ + @Test + public void aPropertiesLineForAnAnnotatedHintIsRefusedNotOverwritten() throws Exception { + File classes = manifest("cn1.buildHints.mainClass=com.example.MyApp\n" + + "cn1.buildHints.sourceDigest=" + + digestOf("@Ios(teamId = \"ABCDE12345\")") + "\n" + + "cn1.buildHints.origin.ios.teamId=@Ios(teamId)\n" + + "codename1.arg.ios.teamId=ABCDE12345\n"); + writeAnnotatedClass(classes); + + Properties target = new Properties(); + target.setProperty("codename1.arg.ios.teamId", "FROMFILE"); + try { + merge(target, classes, "MyApp", "com.example"); + fail("expected the duplicate declaration to be refused"); + } catch (InvocationTargetException ex) { + String message = String.valueOf(ex.getCause().getMessage()); + assertTrue(message, message.contains("declared twice")); + assertTrue(message, message.contains("@Ios(teamId)")); + } + assertEquals("the file's value must not have been replaced", + "FROMFILE", target.getProperty("codename1.arg.ios.teamId")); + } + + /** A hint only the file sets is not a conflict -- that is the escape hatch. */ + @Test + public void aPropertiesLineForAnUnannotatedHintIsLeftAlone() throws Exception { + File classes = manifest("cn1.buildHints.mainClass=com.example.MyApp\n" + + "cn1.buildHints.sourceDigest=" + + digestOf("@Ios(teamId = \"ABCDE12345\")") + "\n" + + "codename1.arg.ios.teamId=ABCDE12345\n"); + writeAnnotatedClass(classes); + + Properties target = new Properties(); + target.setProperty("codename1.arg.ios.pods", "Alamofire"); + + merge(target, classes, "MyApp", "com.example"); + + assertEquals("Alamofire", target.getProperty("codename1.arg.ios.pods")); + assertEquals("ABCDE12345", target.getProperty("codename1.arg.ios.teamId")); + } + // ------------------------------------------------------------------ // helpers // ------------------------------------------------------------------ From b6f16f24650d1990b38cff41c443f663236e6913 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 23:31:45 +0300 Subject: [PATCH 21/23] Catalogue the ten build hints the Wear change added Merged master, which brought in #5583 (complications on the watch, and a Wear artifact beside the phone APK). It adds ten hints the builders read, and the catalog gate failed on the merge result: every hint the code reads has to be described, and the empty baseline means there is nowhere to park one. That is the gate working, not a conflict. #5583 was written before the catalog existed, so it had nothing to add its hints to. Each row's type and default come from the call site rather than from the name: android.blockLabel boolean, false android.surfaces.complicationUpdateSeconds int, 0 android.watchModule boolean, true android.watchVersionCode int, no default -- unset means derive from the offset below android.watchVersionCodeOffset int, 100000000 android.wear.complicationsVersion string, 1.2.1 android.wear.tilesVersion string, 1.4.1 android.wear.protoLayoutVersion string, 1.2.1 android.wear.guavaVersion string, 31.1-android watchNative.surfaces.deploymentTarget string, 10.0 Catalogued, not annotated: the catalog has to describe every hint, but exposing one as a typed attribute is a curation decision, and inventing API for somebody else's feature in a merge commit is not that. They are documented, typed and value-checked, and can be annotated later without churn. The one nuance worth recording is watchNative.surfaces.deploymentTarget, whose default is the watch app's floor rather than the extension's: WidgetKit reaches back to watchOS 9, but the extension is embedded in the watch app, so the lower number would advertise support that does not exist. The regenerated developer-guide table is the only other change -- no annotation churn, as intended. Co-Authored-By: Claude Opus 5 (1M context) --- .../_generated-build-hints.adoc | 60 +++++++++++++ .../build/shared/BuildHintsAndroid.java | 87 +++++++++++++++++++ .../build/shared/BuildHintsApple.java | 11 +++ 3 files changed, 158 insertions(+) diff --git a/docs/developer-guide/_generated-build-hints.adoc b/docs/developer-guide/_generated-build-hints.adoc index 1173af133f9..6eab2c84824 100644 --- a/docs/developer-guide/_generated-build-hints.adoc +++ b/docs/developer-guide/_generated-build-hints.adoc @@ -220,6 +220,12 @@ |_(none)_ |Boolean true/false defaults to false. Disables the external storage (SD card) permission +|android.blockLabel +|boolean +|`false` +|_(none)_ +|Boolean true/false defaults to false. Leaves `android:label` off the generated `` tag so a label set through `android.xapplication_attr` or a merged manifest is the one that survives. Honoured by the wear module's tag as well as the phone's. + |android.blockReadMediaPermissions |boolean |_(none)_ @@ -1026,6 +1032,12 @@ |_(none)_ | +|android.surfaces.complicationUpdateSeconds +|int +|`0` +|_(none)_ +|`UPDATE_PERIOD_SECONDS` on the generated complication service. Zero, the default, means the system never polls on a timer and the complication updates only when the app pushes new data. + |android.surfaces.exactAlarms |boolean |`false` @@ -1110,18 +1122,60 @@ |_(none)_ |Allows overriding the auto generated version number with a custom internal version number specifically used for the XML attribute `android:versionCode` +|android.watchModule +|boolean +|`true` +|_(none)_ +|Boolean true/false defaults to true. Set to false to build the phone app alone in a companion build: the wearable link stays, the watch module is not generated, and the phone output is exactly what it was before the watch app existed. + +|android.watchVersionCode +|int +|_(none)_ +|_(none)_ +|The wear module's version code, stated outright. Play requires it to be higher than the phone's, so a value that is not a whole number above `android.versionCode` fails the build rather than being silently replaced. Unset, it is derived from `android.watchVersionCodeOffset`. + +|android.watchVersionCodeOffset +|int +|`100000000` +|_(none)_ +|How far above the phone's version code the wear module's sits when `android.watchVersionCode` is not set. The default leaves room for the phone app to keep incrementing without ever catching up. + |android.wear |boolean |`false` |_(none)_ | +|android.wear.complicationsVersion +|string +|`1.2.1` +|_(none)_ +|Version of `androidx.wear.watchface:watchface-complications-data-source` added to the wear module. Kept out of `android.gradleDependencies` because that hint feeds the phone module too, and these libraries declare minSdk 26. + +|android.wear.guavaVersion +|string +|`31.1-android` +|_(none)_ +|Version of `com.google.guava:guava` added to the wear module alongside the tiles and complications libraries, which need it at runtime. + +|android.wear.protoLayoutVersion +|string +|`1.2.1` +|_(none)_ +|Version of the `androidx.wear.protolayout` libraries the generated tile service builds its layout with. + |android.wear.standalone |string |_(none)_ |_(none)_ | +|android.wear.tilesVersion +|string +|`1.4.1` +|_(none)_ +|Version of `androidx.wear.tiles` added to the wear module when the app declares a tile. + |android.web_loading_hidden |boolean |`false` @@ -3054,6 +3108,12 @@ |_(none)_ | +|watchNative.surfaces.deploymentTarget +|string +|`10.0` +|_(none)_ +|Deployment target of the WidgetKit extension that carries the watch complication. This is the WATCH APP's floor rather than the extension's own: WidgetKit reaches back to watchOS 9, but the extension is embedded in the watch app, so advertising a version the app itself cannot install on claims support that does not exist. + |win.desktop-vm |string |_(none)_ diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java index ccf306ecffc..f278177df10 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java @@ -301,6 +301,17 @@ static void register(List h) { .consumedBy("AndroidGradleBuilder") .doc("Boolean true/false defaults to false. Disables the external storage (SD card) permission")); + h.add(new Hint("android.blockLabel") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("false") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to false. Leaves `android:label` off the generated " + + "`` tag so a label set through `android.xapplication_attr` or a merged " + + "manifest is the one that survives. Honoured by the wear module's tag as well as the " + + "phone's.")); + h.add(new Hint("android.blockReadMediaPermissions") .group(HintGroup.ANDROID) .type(HintType.BOOLEAN) @@ -1228,6 +1239,16 @@ static void register(List h) { .platform("android") .consumedBy("AndroidGradleBuilder")); + h.add(new Hint("android.surfaces.complicationUpdateSeconds") + .group(HintGroup.ANDROID) + .type(HintType.INT) + .def("0") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("`UPDATE_PERIOD_SECONDS` on the generated complication service. Zero, the default, means " + + "the system never polls on a timer and the complication updates only when the app " + + "pushes new data.")); + h.add(new Hint("android.surfaces.exactAlarms") .group(HintGroup.ANDROID) .type(HintType.BOOLEAN) @@ -1337,6 +1358,36 @@ static void register(List h) { .doc("Allows overriding the auto generated version number with a custom internal version " + "number specifically used for the XML attribute `android:versionCode`")); + h.add(new Hint("android.watchModule") + .group(HintGroup.ANDROID) + .type(HintType.BOOLEAN) + .def("true") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Boolean true/false defaults to true. Set to false to build the phone app alone in a " + + "companion build: the wearable link stays, the watch module is not generated, and the " + + "phone output is exactly what it was before the watch app existed.")); + + h.add(new Hint("android.watchVersionCode") + .group(HintGroup.ANDROID) + .type(HintType.INT) + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("The wear module's version code, stated outright. Play requires it to be higher than the " + + "phone's, so a value that is not a whole number above `android.versionCode` fails the " + + "build rather than being silently replaced. Unset, it is derived from " + + "`android.watchVersionCodeOffset`.")); + + h.add(new Hint("android.watchVersionCodeOffset") + .group(HintGroup.ANDROID) + .type(HintType.INT) + .def("100000000") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("How far above the phone's version code the wear module's sits when " + + "`android.watchVersionCode` is not set. The default leaves room for the phone app to " + + "keep incrementing without ever catching up.")); + h.add(new Hint("android.wear") .group(HintGroup.ANDROID) .type(HintType.BOOLEAN) @@ -1344,6 +1395,42 @@ static void register(List h) { .platform("android") .consumedBy("AndroidGradleBuilder")); + h.add(new Hint("android.wear.complicationsVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("1.2.1") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Version of `androidx.wear.watchface:watchface-complications-data-source` added to the " + + "wear module. Kept out of `android.gradleDependencies` because that hint feeds the " + + "phone module too, and these libraries declare minSdk 26.")); + + h.add(new Hint("android.wear.guavaVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("31.1-android") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Version of `com.google.guava:guava` added to the wear module alongside the tiles and " + + "complications libraries, which need it at runtime.")); + + h.add(new Hint("android.wear.protoLayoutVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("1.2.1") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Version of the `androidx.wear.protolayout` libraries the generated tile service builds " + + "its layout with.")); + + h.add(new Hint("android.wear.tilesVersion") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .def("1.4.1") + .platform("android") + .consumedBy("AndroidGradleBuilder") + .doc("Version of `androidx.wear.tiles` added to the wear module when the app declares a tile.")); + h.add(new Hint("android.wear.standalone") .group(HintGroup.ANDROID) .type(HintType.STRING) diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java index b8abef16dd3..384371d03ae 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java @@ -282,6 +282,17 @@ static void register(List h) { .platform("watch") .consumedBy("WatchNativeBuilder")); + h.add(new Hint("watchNative.surfaces.deploymentTarget") + .group(HintGroup.WATCH_NATIVE) + .type(HintType.STRING) + .def("10.0") + .platform("watch") + .consumedBy("IPhoneBuilder") + .doc("Deployment target of the WidgetKit extension that carries the watch complication. This " + + "is the WATCH APP's floor rather than the extension's own: WidgetKit reaches back to " + + "watchOS 9, but the extension is embedded in the watch app, so advertising a version " + + "the app itself cannot install on claims support that does not exist.")); + h.add(new Hint("watchNative.mainClass") .group(HintGroup.WATCH_NATIVE) .type(HintType.STRING) From eb58dac840f6d3111e262c9ce773b9f3845dac30 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Sun, 23 Aug 2026 23:45:55 +0300 Subject: [PATCH 22/23] Write the new catalog rows in the guide's own voice The developer guide gate treats Vale warnings as errors, and the ten rows added in the previous commit brought seven alerts with them -- the guide requires contractions, so "is not", "cannot", "does not" and "it is" all fail, and "silently" is on the adverb list. Reworded in the catalog, which is where the prose lives; the table is generated from it. The meaning is unchanged in every case, including the two that needed more than a contraction: "a value other than a whole number" rather than "that is not", and "refuses to install on ... support the user never gets" rather than "cannot install on ... does not exist". Vale is clean across all 116 files of the guide. Co-Authored-By: Claude Opus 5 (1M context) --- docs/developer-guide/_generated-build-hints.adoc | 8 ++++---- .../codename1/build/shared/BuildHintsAndroid.java | 12 ++++++------ .../com/codename1/build/shared/BuildHintsApple.java | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/developer-guide/_generated-build-hints.adoc b/docs/developer-guide/_generated-build-hints.adoc index 6eab2c84824..ed0d17f8384 100644 --- a/docs/developer-guide/_generated-build-hints.adoc +++ b/docs/developer-guide/_generated-build-hints.adoc @@ -1126,19 +1126,19 @@ |boolean |`true` |_(none)_ -|Boolean true/false defaults to true. Set to false to build the phone app alone in a companion build: the wearable link stays, the watch module is not generated, and the phone output is exactly what it was before the watch app existed. +|Boolean true/false defaults to true. Set to false to build the phone app alone in a companion build: the wearable link stays, no watch module is generated, and the phone output matches what it was before the watch app existed. |android.watchVersionCode |int |_(none)_ |_(none)_ -|The wear module's version code, stated outright. Play requires it to be higher than the phone's, so a value that is not a whole number above `android.versionCode` fails the build rather than being silently replaced. Unset, it is derived from `android.watchVersionCodeOffset`. +|The wear module's version code, stated outright. Play requires it to be higher than the phone's, so a value other than a whole number above `android.versionCode` fails the build rather than being replaced without a word. Leave it unset to derive the value from `android.watchVersionCodeOffset`. |android.watchVersionCodeOffset |int |`100000000` |_(none)_ -|How far above the phone's version code the wear module's sits when `android.watchVersionCode` is not set. The default leaves room for the phone app to keep incrementing without ever catching up. +|How far above the phone's version code the wear module's sits when `android.watchVersionCode` is unset. The default leaves room for the phone app to keep incrementing without ever catching up. |android.wear |boolean @@ -3112,7 +3112,7 @@ |string |`10.0` |_(none)_ -|Deployment target of the WidgetKit extension that carries the watch complication. This is the WATCH APP's floor rather than the extension's own: WidgetKit reaches back to watchOS 9, but the extension is embedded in the watch app, so advertising a version the app itself cannot install on claims support that does not exist. +|Deployment target of the WidgetKit extension that carries the watch complication. This is the WATCH APP's floor rather than the extension's own: WidgetKit reaches back to watchOS 9, but the extension is embedded in the watch app, so advertising a version the app itself refuses to install on claims support the user never gets. |win.desktop-vm |string diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java index f278177df10..cfae2b80a6e 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java @@ -1365,8 +1365,8 @@ static void register(List h) { .platform("android") .consumedBy("AndroidGradleBuilder") .doc("Boolean true/false defaults to true. Set to false to build the phone app alone in a " - + "companion build: the wearable link stays, the watch module is not generated, and the " - + "phone output is exactly what it was before the watch app existed.")); + + "companion build: the wearable link stays, no watch module is generated, and the " + + "phone output matches what it was before the watch app existed.")); h.add(new Hint("android.watchVersionCode") .group(HintGroup.ANDROID) @@ -1374,9 +1374,9 @@ static void register(List h) { .platform("android") .consumedBy("AndroidGradleBuilder") .doc("The wear module's version code, stated outright. Play requires it to be higher than the " - + "phone's, so a value that is not a whole number above `android.versionCode` fails the " - + "build rather than being silently replaced. Unset, it is derived from " - + "`android.watchVersionCodeOffset`.")); + + "phone's, so a value other than a whole number above `android.versionCode` fails the " + + "build rather than being replaced without a word. Leave it unset to derive the value " + + "from `android.watchVersionCodeOffset`.")); h.add(new Hint("android.watchVersionCodeOffset") .group(HintGroup.ANDROID) @@ -1385,7 +1385,7 @@ static void register(List h) { .platform("android") .consumedBy("AndroidGradleBuilder") .doc("How far above the phone's version code the wear module's sits when " - + "`android.watchVersionCode` is not set. The default leaves room for the phone app to " + + "`android.watchVersionCode` is unset. The default leaves room for the phone app to " + "keep incrementing without ever catching up.")); h.add(new Hint("android.wear") diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java index 384371d03ae..be49840b404 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsApple.java @@ -291,7 +291,7 @@ static void register(List h) { .doc("Deployment target of the WidgetKit extension that carries the watch complication. This " + "is the WATCH APP's floor rather than the extension's own: WidgetKit reaches back to " + "watchOS 9, but the extension is embedded in the watch app, so advertising a version " - + "the app itself cannot install on claims support that does not exist.")); + + "the app itself refuses to install on claims support the user never gets.")); h.add(new Hint("watchNative.mainClass") .group(HintGroup.WATCH_NATIVE) From 9437da72471a246eba6df2115c41ac858b0688e6 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Mon, 24 Aug 2026 11:52:34 +0300 Subject: [PATCH 23/23] Stop the catalog gate claiming coverage it never checked Six from the same review. The miner reads literals, so a hint whose name is BUILT rather than written was invisible to it -- and the gate then printed "all described" while the hint had no catalog row at all. Two shapes occur: getArg(HINT, null) NativeVerifyOption, HINT="nativeVerify" getArg(platform + ".maps.provider", ...) MapsProviderInjector The first is now resolved: a same-file `static final String` whose value is a literal is substituted. The second cannot be -- the platform is only known at run time -- so it is REPORTED rather than skipped. Every site that builds a name must be listed in scripts/build-hint-computed-sites.txt with what it expands to, and every expansion must be catalogued or match a dynamic pattern, so a new one forces a catalog decision instead of disappearing. Only expressions containing a literal are reported; a helper forwarding a variable gets its literal from its caller, which the ordinary pass already mines. Verified both failure modes fire by removing a site and by pointing one at a hint that does not exist. Five sites, three already covered. The two that were not are exactly the ones named: android.maps.provider, ios.maps.provider, and nativeVerify with its ios/linux/windows overrides -- all now in the catalog. The migration trimmed every value. A string, XML or text block can begin or end with meaningful whitespace: an ios.glAppDelegateHeader ending in a newline after a // comment loses it and comments out whatever the builder generates next, and the verification build does not notice because it checks that the key came back, not what it holds. Trimming is now confined to the scalar types, where the space cannot be part of the value. propertyKeyOf did not decode \uXXXX, so a key written codename1.arg.ios... was read as u0069os.teamId, the original line was left in place, and the migration rolled back over a duplicate declaration it had created itself. The Settings source scan missed a Kotlin `import ... as Alias`, under which the annotation's own name appears nowhere. The hint read as unowned, Add wrote the properties line, and the next process-annotations failed on that duplicate. The simulator published a stale manifest without noticing. Judged on timestamps rather than the fingerprint the native path uses -- recomputing that means parsing the class file's annotation table and the simulator has no bytecode reader -- which is sound in the direction that matters, since process-classes always follows compile within a build. It warns and declines to publish rather than running on the previous values of hints it can actually see. codenameone-build-hint-catalog is a runtime dependency of the plugin, so both release gates now confirm it. Without that a Central deploy that reports failure after publishing, or a truncated R2 copy, could advertise a release whose plugin cannot resolve its own dependency. Co-Authored-By: Claude Opus 5 (1M context) --- .../workflows/release-on-maven-central.yml | 21 +++-- .../com/codename1/impl/javase/Simulator.java | 50 +++++++++++ .../_generated-build-hints.adoc | 38 +++++++- .../build/shared/BuildHintsAndroid.java | 7 ++ .../build/shared/BuildHintsDesktop.java | 14 +++ .../build/shared/BuildHintsGeneral.java | 18 +++- .../codename1/build/shared/BuildHintsIos.java | 14 +++ .../maven/MigrateBuildHintsMojo.java | 49 +++++++++-- .../MigrateBuildHintsPropertyParsingTest.java | 16 ++++ scripts/build-hint-computed-sites.txt | 22 +++++ scripts/build_hint_miner.py | 86 ++++++++++++++++++- scripts/check-build-hint-catalog.py | 42 ++++++++- .../settings/CodenameOneSettings.java | 61 +++++++++++-- .../settings/BuildHintCatalogTest.java | 24 ++++++ 14 files changed, 436 insertions(+), 26 deletions(-) create mode 100644 scripts/build-hint-computed-sites.txt diff --git a/.github/workflows/release-on-maven-central.yml b/.github/workflows/release-on-maven-central.yml index aaa3360b592..4303aedc1dc 100644 --- a/.github/workflows/release-on-maven-central.yml +++ b/.github/workflows/release-on-maven-central.yml @@ -113,12 +113,13 @@ jobs: # "Deployment failed while publishing" even when the bundle was # actually accepted and published. As a safety net for that # false-positive case, poll Maven Central for the key artifacts: - # the codenameone-maven-plugin (proxy for the core release), its - # platform-feature-catalog dependency, and both archetypes. The - # catalog is a separate reactor artifact used by the local builders - # for built-in platform dependency selection, so confirming only the - # plugin could leave a released plugin with an unavailable runtime - # dependency. Skipped when the deploy already reported success (the + # the codenameone-maven-plugin (proxy for the core release), the two + # catalogs it depends on at runtime, and both archetypes. Each catalog + # is a separate reactor artifact -- platform-feature-catalog for + # built-in platform dependency selection, build-hint-catalog for the + # build hint table the plugin reads -- so confirming only the plugin + # could leave a released plugin whose own dependency will not resolve. + # Skipped when the deploy already reported success (the # artifacts may still be propagating from Sonatype Central to repo1; # that propagation can take 30+ minutes and isn't worth blocking on). set +e @@ -127,16 +128,19 @@ jobs: "https://repo1.maven.org/maven2/com/codenameone/codenameone-maven-plugin/${GITHUB_REF_NAME}/codenameone-maven-plugin-${GITHUB_REF_NAME}.pom") catalog_code=$(curl -s -o /dev/null -w "%{http_code}" \ "https://repo1.maven.org/maven2/com/codenameone/codenameone-platform-feature-catalog/${GITHUB_REF_NAME}/codenameone-platform-feature-catalog-${GITHUB_REF_NAME}.pom") + hints_code=$(curl -s -o /dev/null -w "%{http_code}" \ + "https://repo1.maven.org/maven2/com/codenameone/codenameone-build-hint-catalog/${GITHUB_REF_NAME}/codenameone-build-hint-catalog-${GITHUB_REF_NAME}.pom") app_code=$(curl -s -o /dev/null -w "%{http_code}" \ "https://repo1.maven.org/maven2/com/codenameone/cn1app-archetype/${GITHUB_REF_NAME}/cn1app-archetype-${GITHUB_REF_NAME}.pom") lib_code=$(curl -s -o /dev/null -w "%{http_code}" \ "https://repo1.maven.org/maven2/com/codenameone/cn1lib-archetype/${GITHUB_REF_NAME}/cn1lib-archetype-${GITHUB_REF_NAME}.pom") if [ "$plugin_code" = "200" ] && [ "$catalog_code" = "200" ] && \ + [ "$hints_code" = "200" ] && \ [ "$app_code" = "200" ] && [ "$lib_code" = "200" ]; then - echo "Confirmed plugin + platform-feature-catalog + cn1{app,lib}-archetype ${GITHUB_REF_NAME} on Maven Central" + echo "Confirmed plugin + platform-feature-catalog + build-hint-catalog + cn1{app,lib}-archetype ${GITHUB_REF_NAME} on Maven Central" exit 0 fi - echo "[$i/90] Waiting on Maven Central (plugin=$plugin_code, catalog=$catalog_code, cn1app=$app_code, cn1lib=$lib_code)" + echo "[$i/90] Waiting on Maven Central (plugin=$plugin_code, catalog=$catalog_code, hints=$hints_code, cn1app=$app_code, cn1lib=$lib_code)" sleep 20 done echo "Artifacts ${GITHUB_REF_NAME} did not appear on Maven Central within 30 minutes" @@ -153,6 +157,7 @@ jobs: # this keeps the release green even if that rule is ever removed. set -e for artifact in codenameone-core codenameone-maven-plugin codenameone-platform-feature-catalog \ + codenameone-build-hint-catalog \ cn1app-archetype cn1lib-archetype; do url="${R2_BASE_URL}/com/codenameone/${artifact}/${GITHUB_REF_NAME}/${artifact}-${GITHUB_REF_NAME}.pom?cb=${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" code=$(curl -s -o /dev/null -w "%{http_code}" "$url") diff --git a/Ports/JavaSE/src/com/codename1/impl/javase/Simulator.java b/Ports/JavaSE/src/com/codename1/impl/javase/Simulator.java index 5fa3c829dba..e7fc7cdf4c7 100644 --- a/Ports/JavaSE/src/com/codename1/impl/javase/Simulator.java +++ b/Ports/JavaSE/src/com/codename1/impl/javase/Simulator.java @@ -503,6 +503,30 @@ private static void publishAnnotationBuildHints(File projectDir) { } } } + File staleAgainst = classNewerThanManifest(projectDir, p, f); + if (staleAgainst != null) { + // Nothing removes target/classes between builds, so a project that ran + // process-annotations once and then stopped -- goal unbound, skipped, + // or bound to a phase that no longer runs -- keeps a manifest that + // looks entirely valid while the annotations beside it have moved on. + // The device build refuses this outright; the simulator would + // otherwise run on the previous values of hints it can actually see, + // such as desktop.titleBar and nativeTheme, and show the wrong thing + // with no indication why. + // + // Judged on timestamps rather than the manifest's own fingerprint: + // recomputing that means parsing the class file's annotation table, + // and the simulator has no bytecode reader. The comparison is sound in + // the direction that matters -- process-classes always follows compile + // within a build, so a main class newer than the manifest cannot have + // produced it. + System.err.println("Warning: " + f + " is older than " + + staleAgainst.getName() + ", so it was produced by an earlier build " + + "and its build hints were NOT applied."); + System.err.println(" Rebuild the project so the cn1 process-annotations " + + "goal regenerates it."); + return; + } int applied = 0; for (String key : p.stringPropertyNames()) { if (!key.startsWith("codename1.arg.")) { @@ -517,4 +541,30 @@ private static void publishAnnotationBuildHints(File projectDir) { System.out.println("Applied " + applied + " build hint(s) from annotations"); } } + + /** + * The compiled main class when it is newer than the manifest, or null. + * + *

Null whenever the question cannot be answered -- no main class recorded, + * no class file for it, no readable timestamps -- so the manifest is taken at + * face value rather than discarded on a guess.

+ */ + private static File classNewerThanManifest(File projectDir, java.util.Properties manifest, + File manifestFile) { + String main = manifest.getProperty("cn1.buildHints.mainClass"); + if (main == null || main.trim().length() == 0) { + return null; + } + File classFile = new File(new File(projectDir, "target" + File.separator + "classes"), + main.trim().replace('.', File.separatorChar) + ".class"); + if (!classFile.isFile()) { + return null; + } + long classTime = classFile.lastModified(); + long manifestTime = manifestFile.lastModified(); + if (classTime == 0L || manifestTime == 0L) { + return null; + } + return classTime > manifestTime ? classFile : null; + } } diff --git a/docs/developer-guide/_generated-build-hints.adoc b/docs/developer-guide/_generated-build-hints.adoc index ed0d17f8384..939eb90d6a6 100644 --- a/docs/developer-guide/_generated-build-hints.adoc +++ b/docs/developer-guide/_generated-build-hints.adoc @@ -636,6 +636,12 @@ |_(none)_ |Embeds XML content into the section of the Android manifest file. This is https://developer.android.com/training/package-visibility[required in Android 11 for package visibility]. See https://developer.android.com/guide/topics/manifest/queries-element[queries element Android documentation]. +|android.maps.provider +|string +|_(none)_ +|_(none)_ +|Android's own native map provider, overriding `maps.provider`. + |android.messagingService |string |_(none)_ @@ -1582,7 +1588,7 @@ |string |_(none)_ |_(none)_ -| +|Selects the native map provider. `android.maps.provider` and `ios.maps.provider` override it for one platform. |nativeTheme |`modern`, `legacy`, `custom` @@ -1590,6 +1596,12 @@ |`@Build(nativeTheme)` |`modern`, `legacy`, `custom` (default unset). Cross-platform override that sets both `ios.themeMode` and `and.themeMode` together when those aren't set explicitly. `modern` = liquid glass + Material 3, `legacy` = iOS 7 flat + Holo Light, `custom` disables the framework native theme entirely. The legacy alias `cn1.nativeTheme` is still accepted. +|nativeVerify +|string +|_(none)_ +|_(none)_ +|`strict` or `warn` turns on ParparVM's native signature check for this build; anything else leaves it off, which is the default. ParparVM encodes the whole Java signature in the C function name, so a native spelled even slightly differently never reaches the linker as an error: the correctly named symbol is simply absent, the dead-code pass reads that as unused, and the feature ships inert. `ios.nativeVerify`, `linux.nativeVerify` and `windows.nativeVerify` override it for one platform. + |noExtraResources |boolean |`false` @@ -2328,6 +2340,12 @@ |_(none)_ | +|ios.maps.provider +|string +|_(none)_ +|_(none)_ +|iOS's own native map provider, overriding `maps.provider`. + |ios.metal |boolean |`true` @@ -2376,6 +2394,12 @@ |_(none)_ |Set to true to enable iOS multitasking and split-screen support. This only works if `ios.xcode_verson=9.2`. +|ios.nativeVerify +|string +|_(none)_ +|_(none)_ +|`nativeVerify` for the iOS translation alone. + |ios.newPipeline |boolean |_(none)_ @@ -2868,6 +2892,12 @@ |_(none)_ | +|linux.nativeVerify +|string +|_(none)_ +|_(none)_ +|`nativeVerify` for the native Linux translation alone. + |linux.toolchain |string |_(none)_ @@ -3198,6 +3228,12 @@ |_(none)_ | +|windows.nativeVerify +|string +|_(none)_ +|_(none)_ +|`nativeVerify` for the native Windows translation alone. + |windows.sdkRoot |string |_(none)_ diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java index cfae2b80a6e..3b081bb3a26 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsAndroid.java @@ -827,6 +827,13 @@ static void register(List h) { .platform("android") .consumedBy("AndroidGradleBuilder")); + h.add(new Hint("android.maps.provider") + .group(HintGroup.ANDROID) + .type(HintType.STRING) + .platform("android") + .consumedBy("MapsProviderInjector") + .doc("Android's own native map provider, overriding `maps.provider`.")); + h.add(new Hint("android.min_sdk_version") .annotatedAs(HintGroup.ANDROID, "minSdkVersion") .type(HintType.INT) diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java index b4c52de1b8e..58aa72d4642 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsDesktop.java @@ -169,6 +169,13 @@ static void register(List h) { .platform("linux") .consumedBy("LinuxNativeBuilder")); + h.add(new Hint("linux.nativeVerify") + .group(HintGroup.LINUX) + .type(HintType.STRING) + .platform("linux") + .consumedBy("LinuxNativeBuilder") + .doc("`nativeVerify` for the native Linux translation alone.")); + h.add(new Hint("linux.cc") .group(HintGroup.LINUX) .type(HintType.STRING) @@ -228,6 +235,13 @@ static void register(List h) { .platform("windows") .consumedBy("WindowsNativeBuilder")); + h.add(new Hint("windows.nativeVerify") + .group(HintGroup.WINDOWS) + .type(HintType.STRING) + .platform("windows") + .consumedBy("WindowsNativeBuilder") + .doc("`nativeVerify` for the native Windows translation alone.")); + h.add(new Hint("windows.debug") .group(HintGroup.WINDOWS) .type(HintType.BOOLEAN) diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java index ef61db1fecb..e1d7b1328f6 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsGeneral.java @@ -342,7 +342,23 @@ static void register(List h) { .group(HintGroup.GENERAL) .type(HintType.STRING) .platform("general") - .consumedBy("MapsProviderInjector")); + .consumedBy("MapsProviderInjector") + .doc("Selects the native map provider. `android.maps.provider` and " + + "`ios.maps.provider` override it for one platform.")); + + h.add(new Hint("nativeVerify") + .group(HintGroup.GENERAL) + .type(HintType.STRING) + .platform("general") + .consumedBy("IPhoneBuilder", "LinuxNativeBuilder", "WindowsNativeBuilder") + .doc("`strict` or `warn` turns on ParparVM's native signature check for this build; " + + "anything else leaves it off, which is the default. ParparVM encodes the whole " + + "Java signature in the C function name, so a native spelled even slightly " + + "differently never reaches the linker as an error: the correctly named symbol " + + "is simply absent, " + + "the dead-code pass reads that as unused, and the feature ships inert. " + + "`ios.nativeVerify`, `linux.nativeVerify` and `windows.nativeVerify` override " + + "it for one platform.")); h.add(new Hint("nativeTheme") .annotatedAs(HintGroup.GENERAL, "nativeTheme") diff --git a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsIos.java b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsIos.java index 242951b086b..08902bc6b30 100644 --- a/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsIos.java +++ b/maven/build-hint-catalog/src/main/java/com/codename1/build/shared/BuildHintsIos.java @@ -737,6 +737,13 @@ static void register(List h) { .platform("ios") .consumedBy("IPhoneBuilder")); + h.add(new Hint("ios.maps.provider") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("MapsProviderInjector") + .doc("iOS's own native map provider, overriding `maps.provider`.")); + h.add(new Hint("ios.metal") .group(HintGroup.IOS) .type(HintType.BOOLEAN) @@ -805,6 +812,13 @@ static void register(List h) { .doc("Set to true to enable iOS multitasking and split-screen support. This only works if " + "`ios.xcode_verson=9.2`.")); + h.add(new Hint("ios.nativeVerify") + .group(HintGroup.IOS) + .type(HintType.STRING) + .platform("ios") + .consumedBy("IPhoneBuilder") + .doc("`nativeVerify` for the iOS translation alone.")); + h.add(new Hint("ios.newStorageLocation") .annotatedAs(HintGroup.IOS, "newStorageLocation") .type(HintType.BOOLEAN) diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java index f5dfd75555b..6976270a0ed 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/MigrateBuildHintsMojo.java @@ -417,21 +417,27 @@ String toSourceLiteral(BuildHints.Hint hint, String value, boolean kotlin) { if (value == null) { return null; } - String v = value.trim(); + // Trimmed only where the surrounding space cannot be part of the value: + // "true ", " 24" and " modern" all mean what they say. A string does not + // get that treatment -- an ios.glAppDelegateHeader ending in a newline + // after a // comment needs that newline, and losing it comments out + // whatever the builder generates next. The verification build would not + // notice, since it checks that the key came back and not what it holds. + String v = value; switch (hint.type()) { case BOOLEAN: - if ("true".equalsIgnoreCase(v)) return "true"; - if ("false".equalsIgnoreCase(v)) return "false"; + if ("true".equalsIgnoreCase(v.trim())) return "true"; + if ("false".equalsIgnoreCase(v.trim())) return "false"; return null; case INT: try { - return String.valueOf(Integer.parseInt(v)); + return String.valueOf(Integer.parseInt(v.trim())); } catch (NumberFormatException ex) { return null; } case ENUM: for (String allowed : hint.values()) { - if (allowed.equalsIgnoreCase(v)) { + if (allowed.equalsIgnoreCase(v.trim())) { return hint.enumName() + "." + enumConstant(allowed); } } @@ -708,7 +714,13 @@ private static boolean continues(String line) { * or a comment. * *

Follows {@code java.util.Properties}: the key runs to the first - * unescaped {@code =}, {@code :} or whitespace.

+ * unescaped {@code =}, {@code :} or whitespace, and {@code \}{@code uXXXX} + * decodes to the character it names. The escape matters because the key this + * returns is compared against one {@code Properties.load} produced: a file + * writing {@code codename1.arg.\}{@code u0069os.teamId} declares + * {@code ios.teamId}, and reading it as {@code u0069os.teamId} leaves the + * original line in place, so the migration rolls back over a duplicate + * declaration it created itself.

*/ static String propertyKeyOf(String logicalLine) { int i = 0; @@ -726,7 +738,17 @@ static String propertyKeyOf(String logicalLine) { for (; i < logicalLine.length(); i++) { char c = logicalLine.charAt(i); if (c == '\\' && i + 1 < logicalLine.length()) { - key.append(logicalLine.charAt(++i)); + char escaped = logicalLine.charAt(++i); + if (escaped == 'u' && i + 4 < logicalLine.length()) { + String hex = logicalLine.substring(i + 1, i + 5); + int value = hexValue(hex); + if (value >= 0) { + key.append((char) value); + i += 4; + continue; + } + } + key.append(escaped); continue; } if (c == '=' || c == ':' || isPropertySpace(c)) { @@ -741,6 +763,19 @@ private static boolean isPropertySpace(char c) { return c == ' ' || c == '\t' || c == '\f'; } + /** Four hex digits as a char value, or -1 when they are not four hex digits. */ + private static int hexValue(String hex) { + int value = 0; + for (int i = 0; i < hex.length(); i++) { + int digit = Character.digit(hex.charAt(i), 16); + if (digit < 0) { + return -1; + } + value = value * 16 + digit; + } + return value; + } + /** The encoding {@code Properties.load(InputStream)} reads. */ private static final String PROPERTIES_ENCODING = "ISO-8859-1"; diff --git a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java index 65d72fdbd9f..5ab19fdb443 100644 --- a/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java +++ b/maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/MigrateBuildHintsPropertyParsingTest.java @@ -139,4 +139,20 @@ public void aBackslashBeforeAnEscapedCharacterSurvives() { public void aControlCharacterIsEscaped() { assertEquals("\"\\u0001\"", MigrateBuildHintsMojo.quoteFor("\u0001", false)); } + + /// `Properties.load` decodes a Unicode escape in a KEY too, so the key this parser + /// returns has to be the decoded one. Reading the escape literally left the + /// original line in place, and the migration then rolled back over a + /// duplicate declaration it had created itself. + @Test + public void aUnicodeEscapeInAKeyIsDecoded() { + assertEquals("codename1.arg.ios.teamId", + MigrateBuildHintsMojo.propertyKeyOf("codename1.arg.\\u0069os.teamId=ABCDE")); + } + + /// Not every backslash-u is an escape. Four hex digits or it is a literal u. + @Test + public void aMalformedUnicodeEscapeIsNotDecoded() { + assertEquals("a.uZZZZb", MigrateBuildHintsMojo.propertyKeyOf("a.\\uZZZZb=1")); + } } diff --git a/scripts/build-hint-computed-sites.txt b/scripts/build-hint-computed-sites.txt new file mode 100644 index 00000000000..0edf7eec13c --- /dev/null +++ b/scripts/build-hint-computed-sites.txt @@ -0,0 +1,22 @@ +# Call sites that BUILD a hint name rather than writing it as a literal, so no +# literal anywhere in the tree names the hint. The miner cannot resolve these -- +# the platform, or the entitlement, is only known at run time -- and before this +# file existed it did not report them either, so the gate could print "all +# described" while android.maps.provider and ios.nativeVerify had no catalog row +# at all. +# +# Every site the miner finds must be listed here with what it expands to, and +# every expansion must be catalogued or match a dynamic pattern. A new computed +# site therefore forces a catalog decision instead of disappearing. +# +# Format: :|[,...] +# +# Only sites whose expression contains a string literal are reported. A helper +# that forwards a variable -- getArg(key, ...) inside a wrapper -- gets its +# literal from its caller, which the ordinary literal pass already mines. + +maven/codenameone-maven-plugin/src/main/java/com/codename1/builders/MapsProviderInjector.java|android.maps.provider,ios.maps.provider +maven/codenameone-maven-plugin/src/main/java/com/codename1/builders/NativeVerifyOption.java|ios.nativeVerify,linux.nativeVerify,windows.nativeVerify +maven/codenameone-maven-plugin/src/main/java/com/codename1/builders/MacNativeBuilder.java|macNative.provisioningProfile.appStore,macNative.provisioningProfile.developerID +maven/codenameone-maven-plugin/src/main/java/com/codename1/builders/IPhoneBuilder.java|ios.entitlements.com.apple.developer.healthkit.access +maven/codenameone-maven-plugin/src/main/java/com/codename1/builders/WatchNativeBuilder.java|ios.entitlements.com.apple.developer.healthkit.access diff --git a/scripts/build_hint_miner.py b/scripts/build_hint_miner.py index 647a308e670..935d7e04c91 100644 --- a/scripts/build_hint_miner.py +++ b/scripts/build_hint_miner.py @@ -9,6 +9,19 @@ because calls nest: getArg("ios.urlSchemes", getArg("ios.urlScheme", "")). A regex that stops at the first comma both mis-reads the outer default and consumes the inner call, silently dropping a hint from the catalog. + +Not every hint name is written as a literal at the point it is read. Two shapes +occur and both used to be invisible, which let the gate report "all described" +while real hints had no catalog row at all: + + getArg(HINT, null) NativeVerifyOption, HINT="nativeVerify" + getArg(platform + ".maps.provider", ...) MapsProviderInjector + +The first is resolved: a `static final String` in the same file whose value is a +literal is substituted. The second cannot be -- the platform is only known at +run time -- so it is reported as a COMPUTED site instead of ignored, and the +checker holds those against the catalog rather than letting them pass in +silence. """ import re, os, sys, json, collections @@ -25,6 +38,15 @@ _ESCAPES = {'n': '\n', 't': '\t', 'r': '\r', 'b': '\b', 'f': '\f', '"': '"', "'": "'", '\\': '\\'} +# getArg/arg/booleanArg whose first argument is not a string literal. \s covers the +# line-wrapped calls, which are plain literal reads once the newline is crossed. +COMPUTED_OPENER = re.compile( + r'\b(?:getArg|booleanArg)\(\s*(?!")|(?= 2 and part.startswith('"') and part.endswith('"'): + lit, _ = read_literal(part, 1) + if lit is None: + return None + out.append(lit) + else: + return None + return "".join(out) for dirpath, _, files in os.walk(SRC): for fn in sorted(files): @@ -91,6 +143,28 @@ def split_args(text, i): with open(path, encoding="utf-8", errors="replace") as fh: text = fh.read() rel = os.path.relpath(path, ROOT) + constants = {m.group(1): (read_literal(m.group(0), m.group(0).index('"') + 1)[0] or "") + for m in CONST_DECL.finditer(text)} + for m in COMPUTED_OPENER.finditer(text): + open_paren = text.rindex('(', m.start(), m.end()) + expr = first_argument(text, open_paren) + if not expr: + continue + line = text.count("\n", 0, m.start()) + 1 + resolved = concat_of_literals(resolve_constants(expr, constants)) + if resolved is not None: + # Fully resolved -- an ordinary hint read that merely spelled its + # name with a constant. + hits[resolved].append(("", rel, line)) + elif '"' in expr: + # The name is being BUILT here, so no literal anywhere names it and + # the literal pass cannot see it. Worth reporting. + computed.append({"expr": " ".join(expr.split()), + "file": rel, "line": line}) + # Anything else is a forwarding helper -- getArg(key, ...) inside a + # wrapper, or the declaration of getArg itself -- whose caller passes a + # literal that the literal pass already mines. Reporting those would bury + # the handful of sites that genuinely compute a name. for pat, prefixed in OPENERS: for m in pat.finditer(text): # position of the char just after the opening quote of arg 1 @@ -112,10 +186,20 @@ def split_args(text, i): line = text.count("\n", 0, m.start()) + 1 hits[key].append((default or "null", rel, line)) +def hits_computed(): + """(expression, file, line) for every site that builds a hint name.""" + return sorted((c["expr"], c["file"], c["line"]) for c in computed) + + if __name__ == "__main__": - print(f"distinct keys mined: {len(hits)}", file=sys.stderr) + print(f"distinct keys mined: {len(hits)}, computed sites: {len(computed)}", + file=sys.stderr) out = sys.argv[1] if len(sys.argv) > 1 else "-" payload = {k: v for k, v in sorted(hits.items())} + # Under a key no hint name can take, so a consumer reading this as a plain + # name->sites map cannot mistake it for a hint. + payload["#computed"] = sorted( + (c["expr"], c["file"], c["line"]) for c in computed) if out == "-": json.dump(payload, sys.stdout, indent=1) else: diff --git a/scripts/check-build-hint-catalog.py b/scripts/check-build-hint-catalog.py index 14e9506e235..b338c58f513 100755 --- a/scripts/check-build-hint-catalog.py +++ b/scripts/check-build-hint-catalog.py @@ -15,6 +15,7 @@ ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.join(ROOT, "scripts")) BASELINE = os.path.join(ROOT, "scripts", "build-hint-catalog-baseline.txt") +COMPUTED_SITES = os.path.join(ROOT, "scripts", "build-hint-computed-sites.txt") CATALOG_CLASSES = os.path.join(ROOT, "maven/build-hint-catalog/target/classes") @@ -147,7 +148,46 @@ def main(): "green build and no effect.", file=sys.stderr) return 1 - print(f"check-build-hint-catalog: {len(miner.hits)} hints read, all described by the catalog" + # Sites that build a hint name instead of writing it. Nothing in the tree + # names the hint they read, so the pass above cannot see it -- which is how + # this gate came to report "all described" while android.maps.provider and + # ios.nativeVerify had no catalog row. + declared = {} + if os.path.exists(COMPUTED_SITES): + with open(COMPUTED_SITES, encoding="utf-8") as fh: + for line in fh: + line = line.strip() + if not line or line.startswith("#"): + continue + where, _, expansions = line.partition("|") + declared[where] = [e for e in expansions.split(",") if e] + + computed_bad = [] + for expr, path, line_no in miner.hits_computed(): + if path not in declared: + computed_bad.append( + f"{path}:{line_no} builds a hint name from `{expr}` and is not listed") + continue + for name in declared[path]: + if name in known or any(fnmatch.fnmatch(name, p) for p in patterns): + continue + computed_bad.append( + f"{path}:{line_no} expands to {name}, which the catalog does not describe") + for path in sorted(set(declared) - {p for _, p, _ in miner.hits_computed()}): + computed_bad.append(f"{path} is listed but no longer builds a hint name") + if computed_bad: + print("check-build-hint-catalog: computed hint names are unaccounted for:", + file=sys.stderr) + for line in sorted(set(computed_bad)): + print(" " + line, file=sys.stderr) + print("\nList the site in scripts/build-hint-computed-sites.txt with what it " + "expands to, and catalogue each expansion. A hint whose name is only ever " + "computed is invisible to every literal search, including this one.", + file=sys.stderr) + return 1 + + print(f"check-build-hint-catalog: {len(miner.hits)} hints read, all described by the " + f"catalog; {len(declared)} computed site(s) accounted for" + (f" ({len(baseline)} baselined)" if baseline else "")) return 0 diff --git a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java index be14fccbed1..9a8db8825b9 100644 --- a/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java +++ b/scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java @@ -2187,6 +2187,45 @@ private String readIfPresent(String path) { } } + /// The name a Kotlin `import ... as Alias` gives an annotation, or null. + /// + /// Kotlin lets a file rename what it imports, and then the annotation never + /// appears under its own name anywhere in the source. Missing that reads the + /// hint as unowned, so Settings offers it for Add, writes the properties + /// line, and the next `process-annotations` fails on the duplicate the tool + /// itself created. + static String kotlinImportAlias(String source, String simple) { + String needle = "com.codename1.annotations.buildhints." + simple; + int at = source.indexOf(needle); + while (at >= 0) { + int after = at + needle.length(); + if (after >= source.length() || !continuesAName(source.charAt(after))) { + int i = after; + while (i < source.length() && (source.charAt(i) == ' ' || source.charAt(i) == '\t')) { + i++; + } + if (source.regionMatches(i, "as", 0, 2) + && i + 2 < source.length() + && !continuesAName(source.charAt(i + 2))) { + i += 2; + while (i < source.length() + && (source.charAt(i) == ' ' || source.charAt(i) == '\t')) { + i++; + } + int start = i; + while (i < source.length() && continuesAName(source.charAt(i))) { + i++; + } + if (i > start) { + return source.substring(start, i); + } + } + } + at = source.indexOf(needle, after); + } + return null; + } + /// Maps every `@Group(attr = ...)` on the main class to the hints it sets. static void collectAnnotationOwnedHints(String source, java.util.Map out) { for (com.codename1.build.shared.BuildHints.Hint h : com.codename1.build.shared.BuildHints.entries()) { @@ -2194,13 +2233,21 @@ static void collectAnnotationOwnedHints(String source, java.util.Map out = new java.util.HashMap(); + CodenameOneSettings.collectAnnotationOwnedHints(src, out); + assertEquals("@Ios(teamId)", out.get("ios.teamId")); + } + + /// The alias only counts when it really is one: the import must say `as`. + @Test + public void aPlainImportIsNotReadAsAnAlias() { + String src = "import com.codename1.annotations.buildhints.Ios\n" + + "@Ios(teamId = \"ABCDE12345\")\n"; + assertNull(CodenameOneSettings.kotlinImportAlias(src, "Ios")); + } }