Skip to content

Conversation

@dilyanpalauzov
Copy link

As spelled at openhab/openhab-docs#2571 the type java.time.ZonedDateTime is available in transformations, is part of the implicit presets. So this sitemap works

sitemap x label="X" {
  Text item=x label="A [GROOVY(|return ZonedDateTime.now();):%s]"
}

This sitemap does not work:

sitemap x label="X" {
  Text item=x label="B [JAVA(|return ZonedDateTime.now();):%s]"
}
2025-10-04 14:23:57.783 [WARN ] [ui.internal.items.ItemUIRegistryImpl] - Failed transforming the value '-' with pattern 'JAVA(|return ZonedDateTime.now();):-': /WrappedJavaScript.java:22: error: cannot find symbol
return ZonedDateTime.now();
       ^
  symbol:   variable ZonedDateTime
  location: class WrappedJavaScript

I have to put prefix java.time. before ZonedDateTime, unless the current patch is applied.

The other thing missing from ScriptWrappingStrategy, but part of the default preset, or rather part of the lifecycle preset, which like the media and default presets is implicitly preloaded, as described at openhab/openhab-docs#2567https://deploy-preview-2567--openhab-docs-preview.netlify.app/docs/configuration/jsr223.html#lifecycle-preset-importpreset-not-required is the lifecycleTracker object.

I think these imports should not be hard-coded in ScriptWrappingStrategy, but somehow implied, when Java223ScriptEngineFactory.scopeValues() is invoked.

@dalgwen
Copy link
Owner

dalgwen commented Oct 6, 2025

Thanks !
I close without merging, because

I think these imports should not be hard-coded in ScriptWrappingStrategy, but somehow implied, when

I added something to do this.

@dalgwen dalgwen closed this Oct 6, 2025
@dilyanpalauzov
Copy link
Author

Now WrappedStrategy inserts:

import java.io.File;                                                                                            
import java.net.URLEncoder;                                                                                     
import java.nio.file.Files;                                                                                     
import java.nio.file.Path;                                                                                      
import java.nio.file.Paths;                                                                                     
import java.time.DayOfWeek;                                                                                     
import java.time.Duration;                                                                                      
import java.time.Month;                                                                                         
import java.time.ZoneId;                                                                                        
import java.time.ZonedDateTime;                                                                                 
import java.time.temporal.ChronoUnit;                                                                           
import org.openhab.core.library.types.DateTimeType;                                                             
import org.openhab.core.library.types.DecimalType;                                                              
import org.openhab.core.library.types.HSBType;                                                                  
import org.openhab.core.library.types.IncreaseDecreaseType;                                                     
import org.openhab.core.library.types.NextPreviousType;                                                         
import org.openhab.core.library.types.OnOffType;                                                                
import org.openhab.core.library.types.OpenClosedType;                                                           
import org.openhab.core.library.types.PercentType;                                                              
import org.openhab.core.library.types.PlayPauseType;                                                            
import org.openhab.core.library.types.PointType;                                                                
import org.openhab.core.library.types.QuantityType;                                                             
import org.openhab.core.library.types.RawType;
import org.openhab.core.library.types.RewindFastforwardType;
import org.openhab.core.library.types.StopMoveType;
import org.openhab.core.library.types.StringListType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.library.types.UpDownType;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
import static org.openhab.core.library.types.IncreaseDecreaseType.DECREASE;
import static org.openhab.core.library.types.IncreaseDecreaseType.INCREASE;
import static org.openhab.core.library.types.NextPreviousType.NEXT;
import static org.openhab.core.library.types.NextPreviousType.PREVIOUS;
import static org.openhab.core.library.types.OnOffType.OFF;
import static org.openhab.core.library.types.OnOffType.ON;
import static org.openhab.core.library.types.OpenClosedType.CLOSED;
import static org.openhab.core.library.types.OpenClosedType.OPEN;
import static org.openhab.core.library.types.PlayPauseType.PAUSE;
import static org.openhab.core.library.types.PlayPauseType.PLAY;
import static org.openhab.core.library.types.RewindFastforwardType.FASTFORWARD;
import static org.openhab.core.library.types.RewindFastforwardType.REWIND;
import static org.openhab.core.library.types.StopMoveType.MOVE;
import static org.openhab.core.library.types.StopMoveType.STOP;
import static org.openhab.core.library.types.UpDownType.DOWN;
import static org.openhab.core.library.types.UpDownType.UP;
import static org.openhab.core.types.RefreshType.REFRESH;
import static org.openhab.core.types.UnDefType.NULL;
import static org.openhab.core.types.UnDefType.UNDEF;




import helper.generated.Java223Script;
import org.openhab.core.library.items.*;
import org.openhab.core.library.types.*;

public class WrappedJavaScript extends Java223Script {                                                          

The last import should not be necessary, as very much things from it (import org.openhab.core.library.types.UpDownType;, import org.openhab.core.library.types.RawType;`) are implicitly imported above. The second last import might also not be necessary, as this is how people are used to work in OH-JSR223. That said, the variable ScriptInterceptorStrategy.BOILERPLATE_CODE_COMMON_IMPORT might not be necessary anymore.

@dilyanpalauzov dilyanpalauzov deleted the wrapping_import_zoneddatetime branch October 6, 2025 12:10
@dilyanpalauzov
Copy link
Author

An alternative way to get the content of the implicit presets is with Java223ScriptEngineFactory.java:

@@ -116,7 +116,10 @@ public class Java223ScriptEngineFactory extends JavaScriptEngineFactory
             @Reference ItemRegistry itemRegistry, @Reference ThingRegistry thingRegistry,
             @Reference Java223DependencyTracker dependencyTracker, @Reference RuleManager ruleManager,
             @Reference ThingManager thingManager, @Reference MetadataRegistry metadataRegistry,
-            @Reference ScriptEngineManager scriptEngineManager) {
+            @Reference ScriptEngineManager scriptEngineManager,
+            @Reference org.openhab.core.automation.module.script.ScriptExtensionAccessor se) {
+        for (var e : se.findDefaultPresets("").entrySet())
+            logger.error("FOUND " + e.getKey() + " VALUE= " + e.getValue().toString());
 
         try {
             Files.createDirectories(LIB_DIR);

which prints:

FOUND voice VALUE= org.openhab.core.voice.internal.VoiceManagerImpl@69c9700e
FOUND DOWN VALUE= DOWN
FOUND StringType VALUE= class org.openhab.core.library.types.StringType
FOUND rules VALUE= org.openhab.core.automation.internal.RuleRegistryImpl@2ccbe353
FOUND NextPreviousType VALUE= class org.openhab.core.library.types.NextPreviousType
FOUND PLAY VALUE= PLAY
FOUND Month VALUE= class java.time.Month
FOUND ImperialUnits VALUE= class org.openhab.core.library.unit.ImperialUnits
FOUND ZonedDateTime VALUE= class java.time.ZonedDateTime
FOUND INCREASE VALUE= INCREASE
FOUND OpenClosedType VALUE= class org.openhab.core.library.types.OpenClosedType
FOUND things VALUE= org.openhab.core.thing.internal.ThingRegistryImpl@47caf75f
FOUND UP VALUE= UP
FOUND RawType VALUE= class org.openhab.core.library.types.RawType
FOUND StringListType VALUE= class org.openhab.core.library.types.StringListType
FOUND events VALUE= org.openhab.core.automation.module.script.internal.defaultscope.ScriptBusEventImpl@1d2deb67
FOUND SIUnits VALUE= class org.openhab.core.library.unit.SIUnits
FOUND itemRegistry VALUE= org.openhab.core.internal.items.ItemRegistryImpl@3fc6a1cc
FOUND NULL VALUE= NULL
FOUND STOP VALUE= STOP
FOUND UnDefType VALUE= class org.openhab.core.types.UnDefType
FOUND ir VALUE= org.openhab.core.internal.items.ItemRegistryImpl@3fc6a1cc
FOUND Duration VALUE= class java.time.Duration
FOUND RefreshType VALUE= class org.openhab.core.types.RefreshType
FOUND Units VALUE= class org.openhab.core.library.unit.Units
FOUND RewindFastforwardType VALUE= class org.openhab.core.library.types.RewindFastforwardType
FOUND DateTimeType VALUE= class org.openhab.core.library.types.DateTimeType
FOUND QuantityType VALUE= class org.openhab.core.library.types.QuantityType
FOUND State VALUE= interface org.openhab.core.types.State
FOUND DecimalType VALUE= class org.openhab.core.library.types.DecimalType
FOUND IncreaseDecreaseType VALUE= class org.openhab.core.library.types.IncreaseDecreaseType
FOUND BinaryPrefix VALUE= class org.openhab.core.library.unit.BinaryPrefix
FOUND File VALUE= class java.io.File
FOUND items VALUE= org.openhab.core.automation.module.script.internal.defaultscope.ItemRegistryDelegate@4ce41c1c
FOUND actions VALUE= org.openhab.core.automation.module.script.internal.defaultscope.ScriptThingActionsImpl@5c846ad0
FOUND CLOSED VALUE= CLOSED
FOUND REFRESH VALUE= REFRESH
FOUND MetricPrefix VALUE= class org.openhab.core.library.unit.MetricPrefix
FOUND DECREASE VALUE= DECREASE
FOUND StopMoveType VALUE= class org.openhab.core.library.types.StopMoveType
FOUND OFF VALUE= OFF
FOUND PREVIOUS VALUE= PREVIOUS
FOUND PAUSE VALUE= PAUSE
FOUND NEXT VALUE= NEXT
FOUND REWIND VALUE= REWIND
FOUND Paths VALUE= class java.nio.file.Paths
FOUND audio VALUE= org.openhab.core.audio.internal.AudioManagerImpl@2e80c4f4
FOUND URLEncoder VALUE= class java.net.URLEncoder
FOUND Files VALUE= class java.nio.file.Files
FOUND HSBType VALUE= class org.openhab.core.library.types.HSBType
FOUND ON VALUE= ON
FOUND Path VALUE= interface java.nio.file.Path
FOUND DayOfWeek VALUE= class java.time.DayOfWeek
FOUND ZoneId VALUE= class java.time.ZoneId
FOUND UpDownType VALUE= class org.openhab.core.library.types.UpDownType
FOUND PercentType VALUE= class org.openhab.core.library.types.PercentType
FOUND OPEN VALUE= OPEN
FOUND MQTTActions VALUE= class org.openhab.binding.mqtt.internal.action.MQTTActions
FOUND MOVE VALUE= MOVE
FOUND OnOffType VALUE= class org.openhab.core.library.types.OnOffType
FOUND Command VALUE= interface org.openhab.core.types.Command
FOUND lifecycleTracker VALUE= org.openhab.core.automation.module.script.LifecycleScriptExtensionProvider$LifecycleTracker@21e8da88
FOUND PlayPauseType VALUE= class org.openhab.core.library.types.PlayPauseType
FOUND FASTFORWARD VALUE= FASTFORWARD
FOUND PointType VALUE= class org.openhab.core.library.types.PointType
FOUND UNDEF VALUE= UNDEF
FOUND ChronoUnit VALUE= class java.time.temporal.ChronoUnit

I think in ScriptWrappingStrategy.BOILERPLATE_CODE_INJECTED_MEMBERS_DECLARATION

protected @InjectBinding ScriptExtensionManagerWrapper scriptExtension;
protected @InjectBinding ScriptExtensionManagerWrapper se;

are not useful in statically compiled languages. It exists to call importPresets() which makes no sense in Java at this moment (because it does not change the state on the server, only calls scriptEngine.put(K, V)). They are also not part of any preset , but injected in the context from org.openhab.core.automation.module.script.internal.ScriptEngineManagerImpl.createScriptEngine() before the implicit presets are loaded.

Can also the variables, besides the types, be imported in the same way, from the output of ScriptExtensionAccessor.findDefaultPresets("")?

As for the instance variables,

  • implements no interfaces;
    ** lifecycleTracker VALUE= org.openhab.core.automation.module.script.LifecycleScriptExtensionProvider$LifecycleTracker@21e8da88
  • implement one interface
    ** events VALUE= org.openhab.core.automation.module.script.internal.defaultscope.ScriptBusEventImpl@1d2deb67
    ** actions VALUE= org.openhab.core.automation.module.script.internal.defaultscope.ScriptThingActionsImpl@5c846ad0
    ** items VALUE= org.openhab.core.automation.module.script.internal.defaultscope.ItemRegistryDelegate@4ce41c1c class ItemRegistryDelegate implements Map<String, State>
  • and implement many interfaces
    ** audio VALUE= org.openhab.core.audio.internal.AudioManagerImpl@2e80c4f4 class AudioManagerImpl implements AudioManager, ConfigOptionProvider
    ** voice VALUE= org.openhab.core.voice.internal.VoiceManagerImpl@69c9700e class VoiceManagerImpl implements VoiceManager, ConfigOptionProvider, DialogProcessor.DialogEventListener
    ** rules VALUE= org.openhab.core.automation.internal.RuleRegistryImpl@2ccbe353 class RuleRegistryImpl extends AbstractRegistry<Rule, String, RuleProvider> implements RuleRegistry, RegistryChangeListener<RuleTemplate>
    ** things VALUE= org.openhab.core.thing.internal.ThingRegistryImpl@47caf75f class ThingRegistryImpl extends AbstractRegistry<Thing, ThingUID, ThingProvider> implements ThingRegistry
    ** itemRegistry VALUE= org.openhab.core.internal.items.ItemRegistryImpl@3fc6a1cc class ItemRegistryImpl extends AbstractRegistry<Item, String, ItemProvider> implements ItemRegistry, RegistryChangeListener<Metadata>
    ** ir VALUE= org.openhab.core.internal.items.ItemRegistryImpl@3fc6a1cc - as above

Can these variables also be inserted from the output of ScriptExtensionManagerWrapper.findDefaultPresets("") in ScriptWrappingStrategy based only on the first implemented interface, or the type (as lifecycleTracker implements no interfaces)?

@dilyanpalauzov
Copy link
Author

With insertion of the variables from the implicit presets in ScriptWrappingStrategy, instead of hard coding them, I mean something like this, Java223ScriptEngineFactory:

@@ -116,7 +116,16 @@ public class Java223ScriptEngineFactory extends JavaScriptEngineFactory
             @Reference ItemRegistry itemRegistry, @Reference ThingRegistry thingRegistry,
             @Reference Java223DependencyTracker dependencyTracker, @Reference RuleManager ruleManager,
             @Reference ThingManager thingManager, @Reference MetadataRegistry metadataRegistry,
-            @Reference ScriptEngineManager scriptEngineManager) {
+            @Reference ScriptEngineManager scriptEngineManager,
+            @Reference org.openhab.core.automation.module.script.ScriptExtensionAccessor se) {
+        for (var e : se.findDefaultPresets("").entrySet())
+            if (!(e.getValue() instanceof Class<?>) && !(e.getValue() instanceof Enum<?>)) {
+                Class<?> i[] = e.getValue().getClass().getInterfaces();
+                if (i.length == 0)
+                    logger.error("OOO " + e.getValue().toString() + " " + e.getKey().toString() + ";");
+                else
+                    logger.error("OOO " + i[0].toGenericString() + " " + e.getKey().toString() + ";");
+            }
 
         try {
             Files.createDirectories(LIB_DIR);

prints

OOO public abstract interface org.openhab.core.voice.VoiceManager voice;
OOO public abstract interface org.openhab.core.automation.RuleRegistry rules;
OOO public abstract interface org.openhab.core.thing.ThingRegistry things;
OOO public abstract interface org.openhab.core.automation.module.script.defaultscope.ScriptBusEvent events;
OOO public abstract interface org.openhab.core.items.ItemRegistry itemRegistry;
OOO public abstract interface org.openhab.core.items.ItemRegistry ir;
OOO public abstract interface java.util.Map<K,V> items;
OOO public abstract interface org.openhab.core.automation.module.script.defaultscope.ScriptThingActions actions;
OOO public abstract interface org.openhab.core.audio.AudioManager audio;
OOO org.openhab.core.automation.module.script.LifecycleScriptExtensionProvider$LifecycleTracker@21e8da88 lifecycleTracker;

@dalgwen
Copy link
Owner

dalgwen commented Oct 7, 2025

       @Reference org.openhab.core.automation.module.script.ScriptExtensionAccessor se) {
   for (var e : se.findDefaultPresets("").entrySet())

Good catch !
So I rewrote it and add dynamic source generation for fields.

Can these variables also be inserted from the output of ScriptExtensionManagerWrapper.findDefaultPresets("") in
ScriptWrappingStrategy based only on the first implemented interface, or the type (as lifecycleTracker implements no interfaces)?

Choosing the first interface feels a bit random.
I choose, when having two or more interface implemented, to rely on a hardcoded preference. And if no hardcoded preferences is found, then the first one is chosen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants