Aller au contenu

Java Code

Résumé

  • Nom interne : JavaCode
  • Catégorie : Système
  • Objectif : Exécuter du code Java inline via un interpréteur de script BeanShell directement sur l'appareil Android.
  • Type de tâche : Normale

Compatibilité

  • Version minimale AndroMate : 1.1.0

  • Version maximale AndroMate : 1.1.0

  • Android minimum : Android 13 (API 33)

  • Android maximum testé : Android 16 (API 36)

  • Constructeurs supportés :

    • Samsung (One UI 6.x / 7.x / 8.x)
    • Autres constructeurs - pas encore supportés (Xiaomi HyperOS et Google Pixel en cours d'adaptation)
  • Permissions requises :

    • Aucune

Description détaillée

La tâche Java Code exécute du code Java inline à l'exécution via BeanShell - un moteur de script Java léger qui supporte la syntaxe Java standard. Le code s'exécute directement sur l'appareil Android dans le processus AndroMate.

Elle est utilisée pour :

  • Effectuer des calculs personnalisés non disponibles via les tâches intégrées
  • Manipuler des chaînes de caractères, des nombres et des structures de données
  • Implémenter une logique conditionnelle ou des boucles dans une seule tâche
  • Traiter les résultats de tâches précédentes avant de les transmettre
  • Déboguer et inspecter des valeurs pendant le développement de workflows

La tâche gère :

  • l'injection de variables de workflow dans le scope de l'interpréteur BeanShell via les entrées Set Variable,
  • l'exécution de blocs de code Java via les entrées Code,
  • la copie d'une variable BeanShell vers une variable de workflow via les entrées Get Variable,
  • l'interception de System.out.println() et le transfert vers la console d'exécution AndroMate,
  • l'interception de System.err.println() et son affichage comme message d'erreur dans la console,
  • la suppression des commentaires // et /* */ avant l'exécution,
  • le découpage du code en blocs à accolades équilibrées évalués séquentiellement.

Remarque : Les messages écrits avec System.out.println("...") dans votre code BeanShell sont capturés et affichés dans la console d'exécution AndroMate en temps réel. C'est particulièrement utile pour déboguer des valeurs de variables ou tracer le flux d'exécution.


Comment fonctionne BeanShell

BeanShell est un moteur de script compatible Java. Il supporte :

  • La syntaxe Java standard (variables, boucles, conditions, appels de méthodes)
  • Les classes de la bibliothèque standard Java (String, Math, Integer, ArrayList, etc.)
  • Le typage dynamique (pas besoin de déclarer explicitement les types)
  • Le code multi-lignes avec des accolades équilibrées { }

Limitations importantes : - Pas d'accès aux APIs Android (ex. Context, Activity) - Pas d'accès au système de fichiers ou au réseau depuis le script - Chaque tâche JavaCode s'exécute dans son propre scope - les variables ne persistent pas entre des tâches JavaCode séparées


Types d'entrées

Le tableau javaCodeEntries définit une séquence d'opérations exécutées dans l'ordre. Il existe trois types d'entrées :

Type d'entrée 1 - Set Variable

Injecte une valeur dans le scope de l'interpréteur BeanShell pour qu'elle soit utilisable dans les entrées Code suivantes.

Champ Type Obligatoire Description
type String Oui Doit être "Set Variable"
variableName String Oui Nom de la variable dans le scope BeanShell
value String Oui Valeur à injecter - peut être une référence $variable_workflow

Résolution de type : La valeur est automatiquement parsée vers le type numérique le plus précis (Integer -> Long -> Float -> String).

Type d'entrée 2 - Code

Exécute un bloc de code Java BeanShell.

Champ Type Obligatoire Description
type String Oui Doit être "Code"
code String Oui Le code Java BeanShell à exécuter

Type d'entrée 3 - Get Variable

Lit une variable BeanShell (créée par une entrée Code précédente) et stocke sa valeur dans une variable de workflow. C'est l'inverse de Set Variable.

Champ Type Obligatoire Description
type String Oui Doit être "Get Variable"
variableName String Oui Nom de la variable du scope BeanShell à lire (sans préfixe $)
targetVariable_output String Oui Variable de workflow qui reçoit la valeur - doit être un nom de variable de workflow comme $resultat

L'ordre compte : les entrées s'exécutent dans l'ordre, donc une entrée Get Variable doit venir après l'entrée Code qui crée la variable.

Conversion de la valeur : les nombres, booléens et chaînes sont stockés en texte ; les listes et tableaux en tableau JSON ; les maps en objet JSON.

targetVariable_output contient le nom de la variable à remplir : $resultat n'est donc jamais remplacé par sa valeur courante avant l'exécution.


Paramètres d'entrée

Paramètre Type Obligatoire Valeurs possibles Compatibilité Android Compatibilité AndroMate Défaut
javaCodeEntries Array Oui Tableau ordonné d'objets d'entrée "Set Variable", "Code" et/ou "Get Variable" - voir la section Types d'entrées Android 13 (API 33) -> Android 16 (API 36) 1.1.0 -> 1.1.0 []

Paramètres de sortie

Cette tâche retourne VoidResult. Les variables de workflow ne sont écrites que par les entrées Get Variable, dans la variable indiquée par targetVariable_output.

Champ Type Condition de déclenchement Compatibilité Android Compatibilité AndroMate Défaut
- VoidResult Toujours - - -

Pour transmettre des valeurs de BeanShell vers le workflow, calculez-les dans une entrée Code, puis ajoutez une entrée Get Variable après elle. Les variables BeanShell ne mettent pas automatiquement à jour les variables du contexte workflow.


Exceptions

Code Nom de l'exception Description
JAVA-CODE-ERROR-001 Type de variable non supporté La valeur fournie dans une entrée Set Variable ne peut pas être mappée vers un type supporté (int, long, float, String).
JAVA-CODE-ERROR-003 Nom ou valeur de variable manquant Une entrée Set Variable n'a pas le champ variableName ou value.
JAVA-CODE-ERROR-004 Champ code manquant Une entrée Code n'a pas le champ code.
JAVA-CODE-ERROR-005 JSON d'entrée malformé Une des entrées dans javaCodeEntries contient du JSON malformé.
JAVA-CODE-ERROR-006 Type d'entrée non supporté Une entrée a une valeur type inconnue - seuls "Code", "Set Variable" et "Get Variable" sont supportés.
JAVA-CODE-ERROR-007 Erreur d'évaluation BeanShell L'interpréteur BeanShell n'a pas pu évaluer le code - erreur de syntaxe, variable indéfinie ou exception runtime dans le script.
JAVA-CODE-ERROR-008 Champs Get Variable manquants Une entrée Get Variable n'a pas variableName ou targetVariable_output.
JAVA-CODE-ERROR-009 Variable Java introuvable La variable BeanShell lue par une entrée Get Variable n'est pas définie - exécutez avant l'entrée Code qui la crée.
JAVA-CODE-ERROR-010 Variable de sortie invalide targetVariable_output n'est pas un nom de variable de workflow valide (par exemple $resultat).
ERROR-000 Autre erreur Une erreur runtime inattendue s'est produite pendant l'exécution.

Diagramme d'exécution

Le diagramme suivant illustre l'implémentation réelle basée sur le code Android :

flowchart TD
    Start([Démarrer JavaCodeTask]) --> ReadEntries[Lire le tableau javaCodeEntries]

    ReadEntries --> Loop{Pour chaque entrée}

    Loop --> CheckType{type de l'entrée ?}

    CheckType -->|Set Variable| ValidateSetVar{variableName\n+ value présents ?}
    ValidateSetVar -->|Non| E3[JAVA-CODE-ERROR-003]
    ValidateSetVar -->|Oui| ParseType[Auto-parser la valeur\nInt -> Long -> Float -> String]
    ParseType --> InjectVar[Injecter la variable\ndans le scope BeanShell]
    InjectVar --> Loop

    CheckType -->|Code| ValidateCode{champ code\nprésent ?}
    ValidateCode -->|Non| E4[JAVA-CODE-ERROR-004]
    ValidateCode -->|Oui| StripComments[Supprimer // et /* */ commentaires]
    StripComments --> SplitBlocks[Découper en blocs\nà accolades équilibrées]
    SplitBlocks --> Eval[BeanShell eval\nchaque bloc]
    Eval -->|EvalError| E7[JAVA-CODE-ERROR-007]
    Eval -->|stdout| Console[System.out -> Console AndroMate]
    Eval -->|stderr| ConsoleErr[System.err -> Console AndroMate]
    Eval -->|Succès| Loop

    CheckType -->|Get Variable| ValidateGetVar{variableName + targetVariable_output\nprésents et valides ?}
    ValidateGetVar -->|Non| E8[JAVA-CODE-ERROR-008 / 010]
    ValidateGetVar -->|Oui| ReadVar[Lire la variable\ndu scope BeanShell]
    ReadVar -->|Non définie| E9[JAVA-CODE-ERROR-009]
    ReadVar -->|Trouvée| StoreVar[Stocker dans la\nvariable de workflow]
    StoreVar --> Loop

    CheckType -->|Inconnu| E6[JAVA-CODE-ERROR-006]

    Loop -->|Toutes les entrées traitées| Success([VoidResult])

    E3 --> Error([Exception])
    E4 --> Error
    E6 --> Error
    E7 --> Error
    E8 --> Error
    E9 --> Error

    style Start fill:#e3f2fd
    style Success fill:#c8e6c9
    style Error fill:#ffcdd2
    style ParseType fill:#fff9c4
    style StripComments fill:#fff9c4
    style SplitBlocks fill:#fff9c4
    style Eval fill:#f3e5f5
    style Console fill:#c8e6c9
    style ConsoleErr fill:#ffe0e0
    style InjectVar fill:#c8e6c9
    style E3 fill:#ffcdd2
    style E4 fill:#ffcdd2
    style E6 fill:#ffcdd2
    style E7 fill:#ffcdd2

Comment ça fonctionne :

  1. Lire les entrées : Charge le tableau javaCodeEntries
  2. Pour chaque entrée - traitées dans l'ordre :
  3. Set Variable : valide les champs -> parse automatiquement le type -> injecte dans le scope BeanShell
  4. Code : supprime les commentaires -> découpe en blocs équilibrés -> évalue chaque bloc
  5. Get Variable : valide les champs -> lit la variable BeanShell -> la stocke dans la variable de workflow
  6. Sortie console : System.out.println() est intercepté et affiché dans la console AndroMate ; System.err est affiché comme erreur
  7. Résultat : Retourne VoidResult en cas de succès

Exemples de code

Exemple 1 - Arithmétique de base et sortie console

{
  "JavaCode": [
    {
      "id": "1",
      "title": "Java Code",
      "javaCodeEntries": [
        {
          "type": "Code",
          "code": "int a = 10;\nint b = 20;\nint result = a + b;\nSystem.out.println(\"Résultat : \" + result);"
        }
      ]
    }
  ]
}

Sortie System.out.println : Résultat : 30 - visible dans la console d'exécution AndroMate.


Exemple 2 - Injecter une variable workflow, calculer, afficher

{
  "JavaCode": [
    {
      "id": "2",
      "title": "Java Code",
      "javaCodeEntries": [
        {
          "type": "Set Variable",
          "variableName": "rttMs",
          "value": "$ntp_rtt"
        },
        {
          "type": "Code",
          "code": "double rttSec = rttMs / 1000.0;\nSystem.out.println(\"RTT en secondes : \" + rttSec);"
        }
      ]
    }
  ]
}

Exemple 3 - Manipulation de chaînes

{
  "JavaCode": [
    {
      "id": "3",
      "title": "Java Code",
      "javaCodeEntries": [
        {
          "type": "Set Variable",
          "variableName": "rawOutput",
          "value": "$cmd_result"
        },
        {
          "type": "Code",
          "code": "String trimmed = rawOutput.trim();\nboolean contains = trimmed.contains(\"unreachable\");\nSystem.out.println(\"Contient unreachable : \" + contains);"
        }
      ]
    }
  ]
}

Exemple 4 - Logique conditionnelle avec trace console

{
  "JavaCode": [
    {
      "id": "4",
      "title": "Java Code",
      "javaCodeEntries": [
        {
          "type": "Set Variable",
          "variableName": "httpStatus",
          "value": "$http_status"
        },
        {
          "type": "Code",
          "code": "if (httpStatus == 200) {\n    System.out.println(\"[OK] Requête réussie\");\n} else {\n    System.err.println(\"[ERREUR] Statut inattendu : \" + httpStatus);\n}"
        }
      ]
    }
  ]
}

Exemple 5 - Boucle et accumulation

{
  "JavaCode": [
    {
      "id": "5",
      "title": "Java Code",
      "javaCodeEntries": [
        {
          "type": "Code",
          "code": "int somme = 0;\nfor (int i = 1; i <= 5; i++) {\n    somme += i;\n    System.out.println(\"Étape \" + i + \" -> somme = \" + somme);\n}\nSystem.out.println(\"Somme finale : \" + somme);"
        }
      ]
    }
  ]
}

Détails des paramètres d'entrée

1. Paramètre d'entrée : javaCodeEntries

Un tableau JSON ordonné d'objets d'entrée exécutés séquentiellement. Il existe trois types d'entrées :

Type d'entrée : "Set Variable"

Injecte une valeur de variable workflow dans le scope de l'interpréteur BeanShell.

Champ Type Obligatoire Description
type String Oui Doit être "Set Variable"
variableName String Oui Nom de la variable dans le scope BeanShell (sans préfixe $)
value String Oui Valeur à injecter - supporte les références $variable_workflow

Résolution automatique de type : la valeur string est automatiquement parsée dans cet ordre : Integer -> Long -> Float -> String. Le type Java résolu est celui que BeanShell voit.

Type d'entrée : "Code"

Exécute un bloc de code Java BeanShell.

Champ Type Obligatoire Description
type String Oui Doit être "Code"
code String Oui Code Java à exécuter - multi-lignes supporté

Pipeline d'exécution : 1. Les commentaires // et /* */ sont supprimés 2. Le code est découpé en blocs à accolades équilibrées { } 3. Chaque bloc est évalué séquentiellement par l'interpréteur BeanShell 4. System.out.println() -> transmis vers la console d'exécution AndroMate 5. System.err.println() -> transmis comme erreur dans la console

Type d'entrée : "Get Variable"

Copie une variable BeanShell dans une variable de workflow (inverse de Set Variable).

Champ Type Obligatoire Description
type String Oui Doit être "Get Variable"
variableName String Oui Nom de la variable BeanShell à lire (sans préfixe $)
targetVariable_output String Oui Variable de workflow qui reçoit la valeur, ex. $resultat

Règles : 1. Doit venir après l'entrée Code qui définit la variable 2. targetVariable_output doit être un nom de variable de workflow ($nom) ; il sert de nom et n'est jamais remplacé par sa valeur courante 3. Listes/tableaux stockés en tableau JSON, maps en objet JSON, le reste en texte

  • Défaut : [] (tableau vide - la tâche ne fait rien)

Exemple JSON complet

{
  "JavaCode": [
    {
      "id": "1",
      "title": "Calculer statistiques RTT",
      "javaCodeEntries": [
        {
          "type": "Set Variable",
          "variableName": "rttMs",
          "value": "$ntp_rtt"
        },
        {
          "type": "Set Variable",
          "variableName": "seuil",
          "value": "200"
        },
        {
          "type": "Code",
          "code": "double rttSec = rttMs / 1000.0;\nSystem.out.println(\"RTT : \" + rttMs + \" ms (\" + rttSec + \" s)\");\nif (rttMs <= seuil) {\n    System.out.println(\"RTT dans la plage acceptable\");\n} else {\n    System.err.println(\"RTT trop élevé : \" + rttMs + \" ms\");\n}"
        },
        {
          "type": "Get Variable",
          "variableName": "rttSec",
          "targetVariable_output": "$rtt_secondes"
        }
      ]
    }
  ]
}