From be3d7ef11d7a4189843705b91c439a32eb7612fd Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 16:52:15 +0200 Subject: [PATCH 01/28] Upgrade pregen command. PregenTask now takes width & height ins o radius --- .../volmit/iris/core/command/CommandIris.java | 1 + .../command/pregen/CommandIrisPregen.java | 65 ++++++ .../pregen/CommandIrisPregenCreate.java | 174 ++++++++++++++++ .../command/pregen/CommandIrisPregenStop.java | 43 ++++ .../pregen/CommandIrisPregenToggle.java | 37 ++++ .../core/command/world/CommandIrisPregen.java | 185 ------------------ .../volmit/iris/core/gui/PregeneratorJob.java | 5 +- .../iris/core/pregenerator/PregenTask.java | 9 +- 8 files changed, 329 insertions(+), 190 deletions(-) create mode 100644 src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java create mode 100644 src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java create mode 100644 src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java create mode 100644 src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenToggle.java delete mode 100644 src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java diff --git a/src/main/java/com/volmit/iris/core/command/CommandIris.java b/src/main/java/com/volmit/iris/core/command/CommandIris.java index dfdee227d..49edcc0f7 100644 --- a/src/main/java/com/volmit/iris/core/command/CommandIris.java +++ b/src/main/java/com/volmit/iris/core/command/CommandIris.java @@ -21,6 +21,7 @@ package com.volmit.iris.core.command; import com.volmit.iris.Iris; import com.volmit.iris.core.command.jigsaw.CommandIrisJigsaw; import com.volmit.iris.core.command.object.CommandIrisObject; +import com.volmit.iris.core.command.pregen.CommandIrisPregen; import com.volmit.iris.core.command.studio.CommandIrisStudio; import com.volmit.iris.core.command.what.CommandIrisWhat; import com.volmit.iris.core.command.world.*; diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java new file mode 100644 index 000000000..6b85af100 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java @@ -0,0 +1,65 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.command.pregen; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.Command; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; + +public class CommandIrisPregen extends MortarCommand { + @Command + private CommandIrisPregenCreate start; + + @Command + private CommandIrisPregenStop stop; + + @Command + private CommandIrisPregenToggle toggle; + + public CommandIrisPregen() { + super("pregen", "preg", "p"); + requiresPermission(Iris.perm); + setCategory("Pregen"); + setDescription("Pregeneration Commands"); + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + if (!IrisToolbelt.isIrisWorld(sender.player().getWorld())){ + sender.sendMessage("Pregen only works in Iris worlds!"); + } + + sender.sendMessage("Iris Pregen Commands:"); + printHelp(sender); + return true; + } + + @Override + protected String getArgsUsage() { + return "[subcommand]"; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java new file mode 100644 index 000000000..24357970b --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java @@ -0,0 +1,174 @@ +package com.volmit.iris.core.command.pregen; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.gui.PregeneratorJob; +import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.checkerframework.checker.units.qual.K; + +import java.util.Arrays; + +public class CommandIrisPregenCreate extends MortarCommand { + + public CommandIrisPregenCreate() { + super("create", "c", "new", "+"); + requiresPermission(Iris.perm); + setCategory("Pregen"); + setDescription("Create a new pregeneration task"); + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + list.add("5000"); + list.add("size=5000 world=IrisWorld x=500 z=-1000"); + list.add("5000 world=IrisWorld x=500 z=-1000"); + list.add("world=IrisWorld x=500 z=-1000"); + for (World w : Bukkit.getServer().getWorlds()) { + list.add(w.getName()); + } + } + + @Override + protected String getArgsUsage() { + return null; + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + + if (PregeneratorJob.getInstance() != null) { + sender.sendMessage("Pregeneration task already ongoing. You can stop it with /ir p stop"); + return true; + } + + World world = null; + int width = -1; + int height = -1; + int x = 0; + int z = 0; + + KList failed = new KList<>(); + for (String a : args) { + if (a.contains("=")) { + String pre = a.split("=")[0]; + String val = a.split("=")[1]; + if (pre.equals("world")){ + world = Bukkit.getWorld(val); + } else if (!isVal(val)){ + sender.sendMessage("Parameters other than `world=` require a number (+ c|chunk|r|region|k), given: '" + a + "' is invalid"); + } else { + switch (pre) { + case "width" -> width = getVal(val); + case "height" -> height = getVal(val); + case "radius" -> { + width = getVal(val); + height = getVal(val); + } + case "x" -> x = getVal(val); + case "z" -> z = getVal(val); + } + } + } else if (isVal(a)) { + width = getVal(a); + height = getVal(a); + } else { + failed.add(a); + } + } + + if (width == -1 || height == -1){ + sender.sendMessage("Size not specified"); + sender.sendMessage(getArgsUsage()); + } + + world = world == null ? sender.player().getWorld() : world; + + KList details = new KList<>( + "Pregeneration details:", + " - World > " + world.getName(), + " - Width/Height > " + width + "/" + height, + " - Center x,z > " + x + "," + z, + failed.isEmpty() ? "(No failed arguments)" : "FAILED ARGS: " + failed + ); + + + if (pregenerate(world, width, height, x, z)){ + sender.sendMessage("Successfully started pregen"); + } else { + sender.sendMessage("Failed to start pregen. Doublecheck your arguments!"); + } + sender.sendMessage(details.array()); + + return true; + } + + /** + * Pregenerate a + * @param world world with a + * @param width and + * @param height with center + * @param x and + * @param z coords + * @return true if successful + */ + private boolean pregenerate(World world, int width, int height, int x, int z){ + try { + IrisToolbelt.pregenerate(PregenTask + .builder() + .center(new Position2(x, z)) + .width(width >> 9 + 1) + .height(height >> 9 + 1) + .build(), world); + } catch (Throwable e){ + Iris.reportError(e); + return false; + } + return true; + } + + private int getVal(String arg) { + + if (arg.toLowerCase().endsWith("c") || arg.toLowerCase().endsWith("chunks")) { + return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qc\\E", "").replaceAll("\\Qchunks\\E", "")) * 16; + } + + if (arg.toLowerCase().endsWith("r") || arg.toLowerCase().endsWith("regions")) { + return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qr\\E", "").replaceAll("\\Qregions\\E", "")) * 512; + } + + if (arg.toLowerCase().endsWith("k")) { + return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qk\\E", "")) * 1000; + } + + return Integer.parseInt(arg.toLowerCase()); + } + + /** + * Checks if the + * @param arg argument + * @return is valid -> true + */ + private boolean isVal(String arg) { + try { + Integer.parseInt( + arg.toLowerCase() + .replace("chunks", "") + .replace("c", "") + .replace("regions", "") + .replace("r", "") + .replace("k", "") + ); + } catch (NumberFormatException e) { + return false; + } + return true; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java new file mode 100644 index 000000000..daa68ef8e --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java @@ -0,0 +1,43 @@ +package com.volmit.iris.core.command.pregen; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.gui.PregeneratorJob; +import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; +import org.bukkit.Bukkit; +import org.bukkit.World; + +public class CommandIrisPregenStop extends MortarCommand { + + public CommandIrisPregenStop() { + super("stop", "s", "x", "close"); + requiresPermission(Iris.perm); + setCategory("Pregen"); + setDescription("Stop an ongoing pregeneration task"); + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + if (PregeneratorJob.shutdownInstance()){ + sender.sendMessage("Stopped pregeneration task"); + } else { + sender.sendMessage("No active pregeneration tasks to stop"); + } + return true; + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + protected String getArgsUsage() { + return null; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenToggle.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenToggle.java new file mode 100644 index 000000000..3406a09fe --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenToggle.java @@ -0,0 +1,37 @@ +package com.volmit.iris.core.command.pregen; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.gui.PregeneratorJob; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; + +public class CommandIrisPregenToggle extends MortarCommand { + + public CommandIrisPregenToggle() { + super("toggle", "t", "pause", "continue", "p", "c"); + requiresPermission(Iris.perm); + setCategory("Pregen"); + setDescription("Toggle an ongoing pregeneration task"); + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + if (PregeneratorJob.pauseResume()){ + sender.sendMessage("Toggled pregeneration task, now: " + (PregeneratorJob.isPaused() ? "Paused" : "Running")); + } else { + sender.sendMessage("No active pregeneration tasks to toggle"); + } + return true; + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + protected String getArgsUsage() { + return null; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java deleted file mode 100644 index cd083c332..000000000 --- a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.core.command.world; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.gui.PregeneratorJob; -import com.volmit.iris.core.pregenerator.PregenTask; -import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod; -import com.volmit.iris.core.tools.IrisToolbelt; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.math.Position2; -import com.volmit.iris.util.plugin.MortarCommand; -import com.volmit.iris.util.plugin.VolmitSender; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.entity.Player; - -import java.awt.*; - -public class CommandIrisPregen extends MortarCommand { - public CommandIrisPregen() { - super("pregen", "preg", "p"); - setDescription( - """ - Pregen this world with optional parameters:\s - '1k' = 1000 * 2 by 1000 * 2 blocks, '1c' = 2 by 2 chunks, and '1r' = 64 by 64 chunks. - If you are using the console or want to pregen a world you're not in: - also specify the name of the world. E.g. /ir pregen 5k world""" - ); - requiresPermission(Iris.perm.studio); - setCategory("Pregen"); - } - - @Override - public void addTabOptions(VolmitSender sender, String[] args, KList list) { - list.add("stop"); - list.add("pause"); - list.add("resume"); - list.add("500"); - list.add("1000"); - list.add("10k"); - list.add("25k"); - list.add("10c"); - list.add("25c"); - list.add("5r"); - list.add("10r"); - for (World w : Bukkit.getServer().getWorlds()) { - list.add(w.getName()); - } - } - - @Override - public boolean handle(VolmitSender sender, String[] args) { - if (args.length == 0) { - sender.sendMessage("/iris pregen "); - return true; - } - - if (args[0].equalsIgnoreCase("stop") || args[0].equalsIgnoreCase("x")) { - if (PregeneratorJob.shutdownInstance()) { - sender.sendMessage("Stopped Pregen. Finishing last region file before shutting down..."); - } else { - sender.sendMessage("No Active Pregens."); - } - return true; - } else if (args[0].equalsIgnoreCase("pause") || args[0].equalsIgnoreCase("resume")) { - if (PregeneratorJob.getInstance() != null) { - PregeneratorJob.pauseResume(); - - if (PregeneratorJob.isPaused()) { - sender.sendMessage("Pregen Paused"); - } else { - sender.sendMessage("Pregen Resumed"); - } - } else { - sender.sendMessage("No Active Pregens"); - } - - return true; - } else if (sender.isPlayer()) { - Player p = sender.player(); - World world; - if (args.length != 2) { - world = p.getWorld(); - } else { - try { - world = Bukkit.getWorld(args[1]); - } catch (Exception e) { - Iris.reportError(e); - sender.sendMessage("Could not find specified world"); - sender.sendMessage("Please doublecheck your command. E.g. /ir pregen 5k world"); - return true; - } - } - try { - IrisToolbelt.pregenerate(PregenTask - .builder() - .center(new Position2(0, 0)) - .radius(((getVal(args[0]) >> 4) >> 5) + 1) - .build(), world); - } catch (NumberFormatException e) { - Iris.reportError(e); - sender.sendMessage("Invalid argument in command"); - return true; - } catch (NullPointerException e) { - Iris.reportError(e); - e.printStackTrace(); - sender.sendMessage("No radius specified (check error in console)"); - } catch (HeadlessException e) { - Iris.reportError(e); - sender.sendMessage("If you are seeing this and are using a hosted server, please turn off 'useServerLaunchedGUIs' in the settings"); - } - - return true; - } else { - if (args.length < 1) { - sender.sendMessage("Please specify the radius of the pregen and the name of the world. E.g. /ir pregen 5k world"); - return true; - } - if (args.length < 2) { - sender.sendMessage("Please specify the name of the world after the command. E.g. /ir pregen 5k world"); - return true; - } - World world = Bukkit.getWorld(args[1]); - try { - new PregeneratorJob(PregenTask - .builder() - .center(new Position2(0, 0)) - .radius(((getVal(args[0]) >> 4) >> 5) + 1) - .build(), - new HybridPregenMethod(world, Runtime.getRuntime().availableProcessors())); - } catch (NumberFormatException e) { - Iris.reportError(e); - sender.sendMessage("Invalid argument in command"); - return true; - } catch (NullPointerException e) { - Iris.reportError(e); - sender.sendMessage("Not all required parameters specified"); - } catch (HeadlessException e) { - Iris.reportError(e); - sender.sendMessage("If you are seeing this and are using a hosted server, please turn off 'useServerLaunchedGUIs' in the settings"); - } - - return true; - } - } - - private int getVal(String arg) { - - if (arg.toLowerCase().endsWith("c") || arg.toLowerCase().endsWith("chunks")) { - return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qc\\E", "").replaceAll("\\Qchunks\\E", "")) * 16; - } - - if (arg.toLowerCase().endsWith("r") || arg.toLowerCase().endsWith("regions")) { - return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qr\\E", "").replaceAll("\\Qregions\\E", "")) * 512; - } - - if (arg.toLowerCase().endsWith("k")) { - return Integer.parseInt(arg.toLowerCase().replaceAll("\\Qk\\E", "")) * 1000; - } - - return Integer.parseInt(arg.toLowerCase()); - } - - @Override - protected String getArgsUsage() { - return "[radius]"; - } -} diff --git a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index 801b98d6f..6757a5a7f 100644 --- a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -103,9 +103,9 @@ public class PregeneratorJob implements PregenListener { return instance; } - public static void pauseResume() { + public static boolean pauseResume() { if (instance == null) { - return; + return false; } if (isPaused()) { @@ -113,6 +113,7 @@ public class PregeneratorJob implements PregenListener { } else { instance.pregenerator.pause(); } + return true; } public static boolean isPaused() { diff --git a/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java b/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java index cc87b439d..5a1907ca3 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java @@ -34,12 +34,15 @@ public class PregenTask { private Position2 center = new Position2(0, 0); @Builder.Default - private int radius = 1; + private int width = 1; + + @Builder.Default + private int height = 1; private static final KList order = computeChunkOrder(); public void iterateRegions(Spiraled s) { - new Spiraler(radius * 2, radius * 2, s) + new Spiraler(getWidth() * 2, getHeight() * 2, s) .setOffset(center.getX(), center.getZ()).drain(); } @@ -50,7 +53,7 @@ public class PregenTask { } public void iterateAllChunks(Spiraled s) { - new Spiraler(radius * 2, radius * 2, (x, z) -> iterateRegion(x, z, s)) + new Spiraler(getWidth() * 2, getHeight() * 2, (x, z) -> iterateRegion(x, z, s)) .setOffset(center.getX(), center.getZ()).drain(); } From 26dee50e6891e4f9a1ff610388c201bd847b9f6f Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 16:54:56 +0200 Subject: [PATCH 02/28] Wikilink --- .../com/volmit/iris/core/command/pregen/CommandIrisPregen.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java index 6b85af100..ce8e818ff 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java @@ -55,6 +55,7 @@ public class CommandIrisPregen extends MortarCommand { sender.sendMessage("Iris Pregen Commands:"); printHelp(sender); + sender.sendMessage("Pregen wiki page: https://docs.volmit.com/iris/pregeneration"); return true; } From 705c5ce79073c3050bd5f535e3db9ad3bfbdc7ce Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 22:20:18 +0200 Subject: [PATCH 03/28] Fix console sender, add descriptions, add -here --- .../command/pregen/CommandIrisPregen.java | 8 +- .../pregen/CommandIrisPregenCreate.java | 76 +++++++++++++++---- 2 files changed, 66 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java index ce8e818ff..5b2b4aaed 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java @@ -49,8 +49,12 @@ public class CommandIrisPregen extends MortarCommand { @Override public boolean handle(VolmitSender sender, String[] args) { - if (!IrisToolbelt.isIrisWorld(sender.player().getWorld())){ - sender.sendMessage("Pregen only works in Iris worlds!"); + if (sender.isPlayer()) { + if (!IrisToolbelt.isIrisWorld(sender.player().getWorld())) { + sender.sendMessage("Pregen only works in Iris worlds!"); + } + } else { + sender.sendMessage("Note that pregeneration only works in Iris worlds!"); } sender.sendMessage("Iris Pregen Commands:"); diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java index 24357970b..53f7f682d 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java @@ -3,7 +3,6 @@ package com.volmit.iris.core.command.pregen; import com.volmit.iris.Iris; import com.volmit.iris.core.gui.PregeneratorJob; import com.volmit.iris.core.pregenerator.PregenTask; -import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.math.Position2; @@ -13,15 +12,28 @@ import org.bukkit.Bukkit; import org.bukkit.World; import org.checkerframework.checker.units.qual.K; -import java.util.Arrays; - public class CommandIrisPregenCreate extends MortarCommand { public CommandIrisPregenCreate() { super("create", "c", "new", "+"); requiresPermission(Iris.perm); setCategory("Pregen"); - setDescription("Create a new pregeneration task"); + setDescription(""" + Create a new pregeneration task. + Command usage & examples: + /iris pregen [radius=] [width=] [height=] [x=] [z=] [world=] [-here] + /iris pregen radius=5000 x=10r z=10r world=IrisWorld + /iris pregen 5k -here + + : Sets both width and height to a value. + & : Give the center point of the pregeneration. + : Specify a specific world name for generation as well (required for console) + -here: If added, the center location is set to your position (player only) + + For all numeric values (radius, centerX, etc.) you may use: + c => 16, r => 512, k => 1000 + Example: entering '1000' is the same as '1k' (1 * 1000) + https://docs.volmit.com/iris/pregeneration"""); } @Override @@ -38,7 +50,7 @@ public class CommandIrisPregenCreate extends MortarCommand { @Override protected String getArgsUsage() { - return null; + return " [width=] [height=] [x=] [z=] [world=] [-here]"; } @Override @@ -54,16 +66,26 @@ public class CommandIrisPregenCreate extends MortarCommand { int height = -1; int x = 0; int z = 0; + boolean here = false; KList failed = new KList<>(); for (String a : args) { - if (a.contains("=")) { + if (a.equals("-here")){ + here = true; + } else if (a.contains("=")) { String pre = a.split("=")[0]; String val = a.split("=")[1]; if (pre.equals("world")){ world = Bukkit.getWorld(val); + if (world == null){ + failed.add(a + " (invalid world)"); + sender.sendMessage("Entered world is " + val + ", but that world does not exist."); + sender.sendMessage("Cancelling the command."); + sender.sendMessage(getDescription()); + return true; + } } else if (!isVal(val)){ - sender.sendMessage("Parameters other than `world=` require a number (+ c|chunk|r|region|k), given: '" + a + "' is invalid"); + failed.add(a + " (non-value)"); } else { switch (pre) { case "width" -> width = getVal(val); @@ -74,31 +96,52 @@ public class CommandIrisPregenCreate extends MortarCommand { } case "x" -> x = getVal(val); case "z" -> z = getVal(val); + default -> failed.add(a + " (no type)"); } } } else if (isVal(a)) { width = getVal(a); height = getVal(a); } else { - failed.add(a); + failed.add(a + " (nothing)"); } } if (width == -1 || height == -1){ - sender.sendMessage("Size not specified"); - sender.sendMessage(getArgsUsage()); + sender.sendMessage("Radius or (width & height) not specified. Cancelling..."); + sender.sendMessage(getDescription()); + return true; } - world = world == null ? sender.player().getWorld() : world; + if (world == null){ + if (sender.isPlayer()){ + world = sender.player().getWorld(); + } else { + sender.sendMessage("Must specify world= if sending from console! Cancelling..."); + sender.sendMessage(getDescription()); + return true; + } + } + + if (here){ + if (sender.isPlayer()) { + x = sender.player().getLocation().getBlockX(); + z = sender.player().getLocation().getBlockZ(); + } else { + sender.sendMessage("Specifying -here does not work from console!"); + } + } KList details = new KList<>( "Pregeneration details:", - " - World > " + world.getName(), - " - Width/Height > " + width + "/" + height, - " - Center x,z > " + x + "," + z, - failed.isEmpty() ? "(No failed arguments)" : "FAILED ARGS: " + failed + " - World > " + world.getName(), + " - Width/Height > " + width + "/" + height, + " - Center x,z > " + x + "," + z, + failed.isEmpty() ? "(No failed arguments)" : "FAILED ARGS:" + ); + failed.forEach(s -> + details.add(" - " + s) ); - if (pregenerate(world, width, height, x, z)){ sender.sendMessage("Successfully started pregen"); @@ -129,6 +172,7 @@ public class CommandIrisPregenCreate extends MortarCommand { .build(), world); } catch (Throwable e){ Iris.reportError(e); + e.printStackTrace(); return false; } return true; From ef51aa7e98fb8096275f35d826abc9071f1fc92a Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 22:22:56 +0200 Subject: [PATCH 04/28] oops --- .../iris/core/command/pregen/CommandIrisPregenCreate.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java index 53f7f682d..d1437e41f 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java @@ -21,9 +21,9 @@ public class CommandIrisPregenCreate extends MortarCommand { setDescription(""" Create a new pregeneration task. Command usage & examples: - /iris pregen [radius=] [width=] [height=] [x=] [z=] [world=] [-here] - /iris pregen radius=5000 x=10r z=10r world=IrisWorld - /iris pregen 5k -here + /iris pregen create [radius=] [width=] [height=] [x=] [z=] [world=] [-here] + /iris pregen create radius=5000 x=10r z=10r world=IrisWorld + /iris pregen create 5k -here : Sets both width and height to a value. & : Give the center point of the pregeneration. From bc53cd1aa4e09108b4fbdd887876ef354314602b Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 22:50:52 +0200 Subject: [PATCH 05/28] Remove empty command descriptions --- .../volmit/iris/core/command/pregen/CommandIrisPregenStop.java | 2 +- .../iris/core/command/pregen/CommandIrisPregenToggle.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java index daa68ef8e..17a864730 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java @@ -38,6 +38,6 @@ public class CommandIrisPregenStop extends MortarCommand { @Override protected String getArgsUsage() { - return null; + return ""; } } diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenToggle.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenToggle.java index 3406a09fe..9e90bf113 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenToggle.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenToggle.java @@ -32,6 +32,6 @@ public class CommandIrisPregenToggle extends MortarCommand { @Override protected String getArgsUsage() { - return null; + return ""; } } From 154aea7a61557655f81f216a0c8e5cbf607bcff2 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 22:51:02 +0200 Subject: [PATCH 06/28] Better autocompletions --- .../pregen/CommandIrisPregenCreate.java | 44 ++++++++++++++++--- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java index d1437e41f..5195987fe 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java @@ -10,10 +10,12 @@ import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; import org.bukkit.Bukkit; import org.bukkit.World; -import org.checkerframework.checker.units.qual.K; + public class CommandIrisPregenCreate extends MortarCommand { + private static final KList argus = new KList<>("radius=", "width=", "height=", "x=", "z="); + public CommandIrisPregenCreate() { super("create", "c", "new", "+"); requiresPermission(Iris.perm); @@ -39,13 +41,41 @@ public class CommandIrisPregenCreate extends MortarCommand { @Override public void addTabOptions(VolmitSender sender, String[] args, KList list) { - list.add("5000"); - list.add("size=5000 world=IrisWorld x=500 z=-1000"); - list.add("5000 world=IrisWorld x=500 z=-1000"); - list.add("world=IrisWorld x=500 z=-1000"); - for (World w : Bukkit.getServer().getWorlds()) { - list.add(w.getName()); + // Add arguments + argus.forEach(p -> { + boolean hasArg = false; + for (String arg : args) { + if (!arg.contains("=") || !p.contains("=")){ + continue; + } + if (arg.split("=")[0].equals(p.split("=")[0])) { + hasArg = true; + break; + } + } + if (!hasArg){ + list.add(p); + } + }); + + // Add -here + boolean hasHere = false; + for (String arg : args) { + if (arg.equals("-here")) { + hasHere = true; + break; + } } + if (!hasHere){ + list.add("-here"); + } + + // Add Iris worlds + Bukkit.getWorlds().forEach(w -> { + if (IrisToolbelt.isIrisWorld(w)){ + list.add("world=" + w.getName()); + } + }); } @Override From c41e34e9d8a960d5dcef187f2629ae194202d0aa Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 22:53:34 +0200 Subject: [PATCH 07/28] Patches autocomplete with no worlds & getString cast error --- .../pregen/CommandIrisPregenCreate.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java index 5195987fe..d7119f089 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java @@ -11,6 +11,8 @@ import com.volmit.iris.util.plugin.VolmitSender; import org.bukkit.Bukkit; import org.bukkit.World; +import java.util.Arrays; + public class CommandIrisPregenCreate extends MortarCommand { @@ -71,11 +73,15 @@ public class CommandIrisPregenCreate extends MortarCommand { } // Add Iris worlds - Bukkit.getWorlds().forEach(w -> { - if (IrisToolbelt.isIrisWorld(w)){ - list.add("world=" + w.getName()); - } - }); + if (Bukkit.getWorlds().isEmpty()){ + list.add("world="); + } else { + Bukkit.getWorlds().forEach(w -> { + if (IrisToolbelt.isIrisWorld(w)) { + list.add("world=" + w.getName()); + } + }); + } } @Override @@ -178,7 +184,7 @@ public class CommandIrisPregenCreate extends MortarCommand { } else { sender.sendMessage("Failed to start pregen. Doublecheck your arguments!"); } - sender.sendMessage(details.array()); + sender.sendMessage(details.toString()); return true; } From 93888aeed334ace3d3adb5495a2b7bdcb0300d62 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 22:58:09 +0200 Subject: [PATCH 08/28] nicer to work with --- .../iris/core/command/pregen/CommandIrisPregenCreate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java index d7119f089..5acec9b70 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java @@ -16,7 +16,7 @@ import java.util.Arrays; public class CommandIrisPregenCreate extends MortarCommand { - private static final KList argus = new KList<>("radius=", "width=", "height=", "x=", "z="); + private static final KList argus = new KList<>("radius=", "width=", "height=", "x=", "z="); public CommandIrisPregenCreate() { super("create", "c", "new", "+"); From cb923cef47f1eee00a705f219bc11af79395389b Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 23:10:44 +0200 Subject: [PATCH 09/28] Details string klist to strinbuilder --- .../pregen/CommandIrisPregenCreate.java | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java index 5acec9b70..b96f832b5 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java @@ -168,16 +168,26 @@ public class CommandIrisPregenCreate extends MortarCommand { } } - KList details = new KList<>( - "Pregeneration details:", - " - World > " + world.getName(), - " - Width/Height > " + width + "/" + height, - " - Center x,z > " + x + "," + z, - failed.isEmpty() ? "(No failed arguments)" : "FAILED ARGS:" - ); - failed.forEach(s -> - details.add(" - " + s) - ); + StringBuilder details = new StringBuilder("Pregeneration details:"); + + details.append("\n") + .append(" - World > ") + .append(world.getName()) + .append("\n") + .append(" - Width/Height > ") + .append(width) + .append("/") + .append(height) + .append("\n") + .append(" - Center x,z > ") + .append(x) + .append(",") + .append(z) + .append("\n") + .append(failed.isEmpty() ? "(No failed arguments)" : "FAILED ARGS:"); + for (String s : failed) { + details.append(s).append("\n"); + } if (pregenerate(world, width, height, x, z)){ sender.sendMessage("Successfully started pregen"); From dafa3bde8be31ad07f129dadfd4560c384dea2c2 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 23:13:54 +0200 Subject: [PATCH 10/28] Newline & append --- .../iris/core/command/pregen/CommandIrisPregenCreate.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java index b96f832b5..a846c5ff7 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java @@ -184,15 +184,15 @@ public class CommandIrisPregenCreate extends MortarCommand { .append(",") .append(z) .append("\n") - .append(failed.isEmpty() ? "(No failed arguments)" : "FAILED ARGS:"); + .append(failed.isEmpty() ? "(No failed arguments)" : "FAILED ARGS:\n"); for (String s : failed) { details.append(s).append("\n"); } if (pregenerate(world, width, height, x, z)){ - sender.sendMessage("Successfully started pregen"); + details.append("Successfully started pregen"); } else { - sender.sendMessage("Failed to start pregen. Doublecheck your arguments!"); + details.append("Failed to start pregen. Doublecheck your arguments!"); } sender.sendMessage(details.toString()); From 14d2ae0c0e8e38cabb277587c71a4ba8e2d1e6d5 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 23:15:22 +0200 Subject: [PATCH 11/28] Use toolbelt instead of Irisworlds --- src/main/java/com/volmit/iris/Iris.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 623e4caf5..da553c005 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -29,6 +29,7 @@ import com.volmit.iris.core.link.MythicMobsLink; import com.volmit.iris.core.link.OraxenLink; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.EngineCompositeGenerator; import com.volmit.iris.engine.object.biome.IrisBiome; @@ -267,8 +268,8 @@ public class Iris extends VolmitPlugin implements Listener { proj.close(); for (World i : Bukkit.getWorlds()) { - if (IrisWorlds.isIrisWorld(i)) { - IrisWorlds.access(i).close(); + if (IrisToolbelt.isIrisWorld(i)) { + IrisToolbelt.access(i).close(); } } From dff6048a0775272fc1cad51edb7f54e01eb8e239 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 7 Aug 2021 19:25:59 +0200 Subject: [PATCH 12/28] Rename class, update nodes, update messages --- .../iris/core/command/pregen/CommandIrisPregen.java | 2 +- ...isPregenToggle.java => CommandIrisPregenPause.java} | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) rename src/main/java/com/volmit/iris/core/command/pregen/{CommandIrisPregenToggle.java => CommandIrisPregenPause.java} (71%) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java index 5b2b4aaed..7e5cba61f 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java @@ -33,7 +33,7 @@ public class CommandIrisPregen extends MortarCommand { private CommandIrisPregenStop stop; @Command - private CommandIrisPregenToggle toggle; + private CommandIrisPregenPause toggle; public CommandIrisPregen() { super("pregen", "preg", "p"); diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenToggle.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenPause.java similarity index 71% rename from src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenToggle.java rename to src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenPause.java index 9e90bf113..66d324d3d 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenToggle.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenPause.java @@ -6,10 +6,10 @@ import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; -public class CommandIrisPregenToggle extends MortarCommand { +public class CommandIrisPregenPause extends MortarCommand { - public CommandIrisPregenToggle() { - super("toggle", "t", "pause", "continue", "p", "c"); + public CommandIrisPregenPause() { + super("pause", "toggle", "t", "continue", "resume", "p", "c", "unpause", "up"); requiresPermission(Iris.perm); setCategory("Pregen"); setDescription("Toggle an ongoing pregeneration task"); @@ -18,9 +18,9 @@ public class CommandIrisPregenToggle extends MortarCommand { @Override public boolean handle(VolmitSender sender, String[] args) { if (PregeneratorJob.pauseResume()){ - sender.sendMessage("Toggled pregeneration task, now: " + (PregeneratorJob.isPaused() ? "Paused" : "Running")); + sender.sendMessage("Paused/unpaused pregeneration task, now: " + (PregeneratorJob.isPaused() ? "Paused" : "Running") + "."); } else { - sender.sendMessage("No active pregeneration tasks to toggle"); + sender.sendMessage("No active pregeneration tasks to pause/unpause."); } return true; } From a0df548dd305f90cb49f82b4e823d92531a8a876 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 7 Aug 2021 19:50:02 +0200 Subject: [PATCH 13/28] IrisPregenStart repl. IrisPregenCreate + fixes --- .../command/pregen/CommandIrisPregen.java | 2 +- ...reate.java => CommandIrisPregenStart.java} | 77 +++++++++++++------ 2 files changed, 56 insertions(+), 23 deletions(-) rename src/main/java/com/volmit/iris/core/command/pregen/{CommandIrisPregenCreate.java => CommandIrisPregenStart.java} (76%) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java index 7e5cba61f..53fdf10c9 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregen.java @@ -27,7 +27,7 @@ import com.volmit.iris.util.plugin.VolmitSender; public class CommandIrisPregen extends MortarCommand { @Command - private CommandIrisPregenCreate start; + private CommandIrisPregenStart start; @Command private CommandIrisPregenStop stop; diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java similarity index 76% rename from src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java rename to src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java index a846c5ff7..d5ded0cc8 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenCreate.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java @@ -14,25 +14,31 @@ import org.bukkit.World; import java.util.Arrays; -public class CommandIrisPregenCreate extends MortarCommand { +public class CommandIrisPregenStart extends MortarCommand { private static final KList argus = new KList<>("radius=", "width=", "height=", "x=", "z="); - public CommandIrisPregenCreate() { - super("create", "c", "new", "+"); + public CommandIrisPregenStart() { + super("start", "s", "create", "c", "new", "+"); requiresPermission(Iris.perm); setCategory("Pregen"); setDescription(""" Create a new pregeneration task. - Command usage & examples: - /iris pregen create [radius=] [width=] [height=] [x=] [z=] [world=] [-here] - /iris pregen create radius=5000 x=10r z=10r world=IrisWorld - /iris pregen create 5k -here + Command usage: + /iris pregen create [radius=] [x=] [z=] [world=] [-here] - : Sets both width and height to a value. - & : Give the center point of the pregeneration. - : Specify a specific world name for generation as well (required for console) + Examples: + /iris pregen start 5k -here + /iris pregen start radius=5000 x=10r z=10r world=IrisWorld + /iris pregen start 10k world=WorldName + + : Sets both width and height to a value. (Size is: 2 * radius by 2 * radius) + & : Give the center point of the pregen. + : Specify a different world name for generation than the one you're currently in. + The console is not in any world, so this is required for console! + If you specify this, the `-here` is ignored. -here: If added, the center location is set to your position (player only) + This overrides and . For all numeric values (radius, centerX, etc.) you may use: c => 16, r => 512, k => 1000 @@ -86,14 +92,15 @@ public class CommandIrisPregenCreate extends MortarCommand { @Override protected String getArgsUsage() { - return " [width=] [height=] [x=] [z=] [world=] [-here]"; + return " [x=] [z=] [world=] [-here]"; } @Override public boolean handle(VolmitSender sender, String[] args) { if (PregeneratorJob.getInstance() != null) { - sender.sendMessage("Pregeneration task already ongoing. You can stop it with /ir p stop"); + sender.sendMessage("Pregeneration task already ongoing. You can stop it with /ir p stop."); + sender.sendMessage("Cannot create new pregen while one is already going. Cancelling..."); return true; } @@ -104,6 +111,7 @@ public class CommandIrisPregenCreate extends MortarCommand { int z = 0; boolean here = false; + // Check all arguments KList failed = new KList<>(); for (String a : args) { if (a.equals("-here")){ @@ -143,12 +151,14 @@ public class CommandIrisPregenCreate extends MortarCommand { } } + // Checking if a radius was specified or forgotten if (width == -1 || height == -1){ - sender.sendMessage("Radius or (width & height) not specified. Cancelling..."); + sender.sendMessage("Radius not specified! Cancelling..."); sender.sendMessage(getDescription()); return true; } + // World specified & cancelling `-here` if it's another world if (world == null){ if (sender.isPlayer()){ world = sender.player().getWorld(); @@ -157,8 +167,18 @@ public class CommandIrisPregenCreate extends MortarCommand { sender.sendMessage(getDescription()); return true; } + } else { + if (sender.isPlayer()){ + if (!world.equals(sender.player().getWorld())){ + if (here) { + sender.sendMessage("Ignoring `-here` because `world=` is specified!"); + here = false; + } + } + } } + // Checking if -here is used if (here){ if (sender.isPlayer()) { x = sender.player().getLocation().getBlockX(); @@ -168,32 +188,39 @@ public class CommandIrisPregenCreate extends MortarCommand { } } - StringBuilder details = new StringBuilder("Pregeneration details:"); - - details.append("\n") + // Build details print + StringBuilder details = new StringBuilder("Pregeneration details:") + .append("\n") .append(" - World > ") .append(world.getName()) .append("\n") - .append(" - Width/Height > ") + .append(" - Radius > ") .append(width) - .append("/") - .append(height) - .append("\n") + .append("(") + .append(width * 2) + .append(" by ") + .append(height * 2) + .append(")\n") .append(" - Center x,z > ") .append(x) .append(",") .append(z) .append("\n") - .append(failed.isEmpty() ? "(No failed arguments)" : "FAILED ARGS:\n"); + + // Append failed args + .append(failed.isEmpty() ? "(No failed arguments)\n" : "FAILED ARGS:\n"); for (String s : failed) { details.append(s).append("\n"); } + // Start pregen and append info to details if (pregenerate(world, width, height, x, z)){ details.append("Successfully started pregen"); } else { details.append("Failed to start pregen. Doublecheck your arguments!"); } + + // Send details sender.sendMessage(details.toString()); return true; @@ -224,6 +251,12 @@ public class CommandIrisPregenCreate extends MortarCommand { return true; } + /** + * Get the ingeger value from an argument that may contain `c` `chunks` `r` `regions` or `k`
+ * "5r" returns 5 * 512 = 2560 + * @param arg the string argument to parse into a value + * @return the integer value result + */ private int getVal(String arg) { if (arg.toLowerCase().endsWith("c") || arg.toLowerCase().endsWith("chunks")) { @@ -243,7 +276,7 @@ public class CommandIrisPregenCreate extends MortarCommand { /** * Checks if the - * @param arg argument + * @param arg string value * @return is valid -> true */ private boolean isVal(String arg) { From cf76e438983f64e77004e05e72d57b65c423d062 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 7 Aug 2021 19:53:32 +0200 Subject: [PATCH 14/28] Forgot to remove width&height from autcomplete --- .../volmit/iris/core/command/pregen/CommandIrisPregenStart.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java index d5ded0cc8..1c0ea3342 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java @@ -16,7 +16,7 @@ import java.util.Arrays; public class CommandIrisPregenStart extends MortarCommand { - private static final KList argus = new KList<>("radius=", "width=", "height=", "x=", "z="); + private static final KList argus = new KList<>("radius=", "x=", "z="); public CommandIrisPregenStart() { super("start", "s", "create", "c", "new", "+"); From fb32d11d6468461d2ed1190d30e71dd8c334b3a2 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 7 Aug 2021 20:38:05 +0200 Subject: [PATCH 15/28] Copy pasta eaten and processed :] --- .../com/volmit/iris/core/command/what/CommandIrisWhat.java | 3 +-- .../volmit/iris/core/command/what/CommandIrisWhatBiome.java | 1 - .../volmit/iris/core/command/what/CommandIrisWhatBlock.java | 3 +-- .../volmit/iris/core/command/what/CommandIrisWhatFeatures.java | 1 - .../com/volmit/iris/core/command/what/CommandIrisWhatHand.java | 3 +-- .../volmit/iris/core/command/what/CommandIrisWhatObjects.java | 2 +- 6 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhat.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhat.java index 3651c024d..b979e6668 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhat.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhat.java @@ -42,7 +42,6 @@ public class CommandIrisWhat extends MortarCommand { public CommandIrisWhat() { super("what", "w", "?"); - setDescription("Get timings for this world"); requiresPermission(Iris.perm.studio); setCategory("Wut"); setDescription("Figure out what stuff is"); @@ -62,6 +61,6 @@ public class CommandIrisWhat extends MortarCommand { @Override protected String getArgsUsage() { - return ""; + return "[subcommand]"; } } diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java index d26ad8eee..00a6929f1 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java @@ -33,7 +33,6 @@ import org.bukkit.entity.Player; public class CommandIrisWhatBiome extends MortarCommand { public CommandIrisWhatBiome() { super("biome", "bi", "b"); - setDescription("Get the biome data you are in."); requiresPermission(Iris.perm.studio); setCategory("Wut"); setDescription("What biome am I in"); diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBlock.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBlock.java index 780985b46..818d1ecb3 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBlock.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBlock.java @@ -31,10 +31,9 @@ import org.bukkit.entity.Player; public class CommandIrisWhatBlock extends MortarCommand { public CommandIrisWhatBlock() { super("block", "l", "bl"); - setDescription("Get the block data for looking."); + setDescription("Get the block data of the block you're looking at."); requiresPermission(Iris.perm.studio); setCategory("Wut"); - setDescription("WAILA, WAWLA etc"); } @Override diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java index 30a3bf329..379a81241 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java @@ -37,7 +37,6 @@ public class CommandIrisWhatFeatures extends MortarCommand { setDescription("Get the noise feature data in chunk."); requiresPermission(Iris.perm.studio); setCategory("Wut"); - setDescription("WAILA, WAWLA etc"); } @Override diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatHand.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatHand.java index b5ad52fa5..9158da06b 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatHand.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatHand.java @@ -30,10 +30,9 @@ import org.bukkit.entity.Player; public class CommandIrisWhatHand extends MortarCommand { public CommandIrisWhatHand() { super("hand", "h"); - setDescription("Get the block data for holding."); + setDescription("Get the block data for the block you're holding."); requiresPermission(Iris.perm.studio); setCategory("Wut"); - setDescription("What block am I holding"); } @Override diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java index b949de69e..b23f705f9 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java @@ -51,7 +51,7 @@ import java.util.Objects; public class CommandIrisWhatObjects extends MortarCommand { public CommandIrisWhatObjects() { super("objects", "o", "obj", "capture", "capt"); - setDescription("Capture nearby information to help with reporting problems"); + setDescription("Capture nearby information to help with reporting problems. Can specify the number of threads like /ir w o 4"); requiresPermission(Iris.perm.studio); setCategory("World"); } From ac6ccd2dc76ac535c44b68a39b74d8965b6a6902 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Sat, 7 Aug 2021 21:07:18 +0200 Subject: [PATCH 16/28] Another one --- .../com/volmit/iris/core/command/jigsaw/CommandIrisJigsaw.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsaw.java b/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsaw.java index fce3ce457..78e8193ca 100644 --- a/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsaw.java +++ b/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsaw.java @@ -69,6 +69,6 @@ public class CommandIrisJigsaw extends MortarCommand { @Override protected String getArgsUsage() { - return ""; + return "[subcommand]"; } } From 18465cf6cbbcb10141879b7efc8f4f33827f4f0b Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sat, 7 Aug 2021 21:18:39 -0400 Subject: [PATCH 17/28] Add BSF --- build.gradle | 5 +- .../iris/engine/IrisExecutionEnvironment.java | 33 + .../scripting/EngineExecutionEnvironment.java | 31 + .../volmit/iris/util/bsf/BSFDeclaredBean.java | 39 + .../com/volmit/iris/util/bsf/BSFEngine.java | 253 +++++ .../volmit/iris/util/bsf/BSFException.java | 71 ++ .../com/volmit/iris/util/bsf/BSFManager.java | 913 ++++++++++++++++++ .../volmit/iris/util/bsf/Languages.properties | 50 + .../java/com/volmit/iris/util/bsf/Main.java | 190 ++++ .../util/bsf/engines/jacl/BSFCommand.java | 107 ++ .../util/bsf/engines/jacl/JaclEngine.java | 136 +++ .../util/bsf/engines/java/JavaEngine.java | 352 +++++++ .../engines/javaclass/JavaClassEngine.java | 73 ++ .../engines/javascript/JavaScriptEngine.java | 233 +++++ .../util/bsf/engines/jython/JythonEngine.java | 244 +++++ .../bsf/engines/netrexx/NetRexxEngine.java | 497 ++++++++++ .../util/bsf/engines/xslt/XSLTEngine.java | 193 ++++ .../util/bsf/engines/xslt/XSLTResultNode.java | 33 + .../iris/util/bsf/util/BSFClassLoader.java | 74 ++ .../iris/util/bsf/util/BSFEngineImpl.java | 203 ++++ .../iris/util/bsf/util/BSFEventProcessor.java | 92 ++ .../BSFEventProcessorReturningEventInfos.java | 164 ++++ .../iris/util/bsf/util/BSFFunctions.java | 54 ++ .../com/volmit/iris/util/bsf/util/Bean.java | 38 + .../volmit/iris/util/bsf/util/CodeBuffer.java | 479 +++++++++ .../iris/util/bsf/util/EngineUtils.java | 379 ++++++++ .../volmit/iris/util/bsf/util/IOUtils.java | 51 + .../iris/util/bsf/util/IndentWriter.java | 85 ++ .../com/volmit/iris/util/bsf/util/JNIUtils.c | 228 +++++ .../com/volmit/iris/util/bsf/util/JNIUtils.h | 62 ++ .../volmit/iris/util/bsf/util/JavaUtils.java | 55 ++ .../iris/util/bsf/util/MethodUtils.java | 517 ++++++++++ .../volmit/iris/util/bsf/util/ObjInfo.java | 88 ++ .../iris/util/bsf/util/ObjectRegistry.java | 63 ++ .../iris/util/bsf/util/ReflectionUtils.java | 421 ++++++++ .../iris/util/bsf/util/ScriptSymbolTable.java | 44 + .../iris/util/bsf/util/StringUtils.java | 412 ++++++++ .../iris/util/bsf/util/cf/CFDriver.java | 196 ++++ .../iris/util/bsf/util/cf/CodeFormatter.java | 372 +++++++ .../util/bsf/util/event/EventAdapter.java | 35 + .../util/bsf/util/event/EventAdapterImpl.java | 35 + .../bsf/util/event/EventAdapterRegistry.java | 103 ++ .../util/bsf/util/event/EventProcessor.java | 35 + .../java_awt_event_ActionAdapter.java | 30 + .../java_awt_event_AdjustmentAdapter.java | 30 + .../java_awt_event_ComponentAdapter.java | 39 + .../java_awt_event_ContainerAdapter.java | 33 + .../adapters/java_awt_event_FocusAdapter.java | 33 + .../adapters/java_awt_event_ItemAdapter.java | 30 + .../adapters/java_awt_event_KeyAdapter.java | 36 + .../adapters/java_awt_event_MouseAdapter.java | 42 + .../java_awt_event_MouseMotionAdapter.java | 33 + .../adapters/java_awt_event_TextAdapter.java | 30 + .../java_awt_event_WindowAdapter.java | 48 + .../java_beans_PropertyChangeAdapter.java | 30 + .../java_beans_VetoableChangeAdapter.java | 41 + .../event/generator/AdapterClassLoader.java | 102 ++ .../bsf/util/event/generator/ByteUtility.java | 331 +++++++ .../bsf/util/event/generator/Bytecode.java | 105 ++ .../generator/EventAdapterGenerator.java | 568 +++++++++++ .../util/bsf/util/type/TypeConvertor.java | 31 + .../bsf/util/type/TypeConvertorRegistry.java | 206 ++++ 62 files changed, 9534 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java create mode 100644 src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/BSFDeclaredBean.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/BSFEngine.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/BSFException.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/BSFManager.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/Languages.properties create mode 100644 src/main/java/com/volmit/iris/util/bsf/Main.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/jacl/BSFCommand.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/jacl/JaclEngine.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/java/JavaEngine.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/javaclass/JavaClassEngine.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/javascript/JavaScriptEngine.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/jython/JythonEngine.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/netrexx/NetRexxEngine.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTEngine.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTResultNode.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/BSFClassLoader.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/BSFEngineImpl.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessor.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessorReturningEventInfos.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/BSFFunctions.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/Bean.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/CodeBuffer.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/EngineUtils.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/IOUtils.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/IndentWriter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.c create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.h create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/JavaUtils.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/MethodUtils.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/ObjInfo.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/ObjectRegistry.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/ReflectionUtils.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/ScriptSymbolTable.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/StringUtils.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/cf/CFDriver.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/cf/CodeFormatter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterImpl.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterRegistry.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/EventProcessor.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ActionAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_AdjustmentAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ComponentAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ContainerAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_FocusAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ItemAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_KeyAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseMotionAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_TextAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_WindowAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_PropertyChangeAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_VetoableChangeAdapter.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/generator/AdapterClassLoader.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/generator/ByteUtility.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/generator/Bytecode.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/generator/EventAdapterGenerator.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertor.java create mode 100644 src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertorRegistry.java diff --git a/build.gradle b/build.gradle index 0cc7bd840..b421f0183 100644 --- a/build.gradle +++ b/build.gradle @@ -137,8 +137,8 @@ dependencies { implementation "net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT" implementation "net.kyori:adventure-platform-bukkit:4.0.0-SNAPSHOT" implementation 'net.kyori:adventure-api:4.8.1' -\ -// Dynamically Loaded + + // Dynamically Loaded implementation 'it.unimi.dsi:fastutil:8.5.4' implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2' implementation 'org.zeroturnaround:zt-zip:1.14' @@ -146,4 +146,5 @@ dependencies { implementation 'org.ow2.asm:asm:9.2' implementation 'com.google.guava:guava:30.1.1-jre' + } \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java new file mode 100644 index 000000000..e8896350d --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java @@ -0,0 +1,33 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine; + +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.scripting.EngineExecutionEnvironment; +import lombok.Data; + +@Data +public class IrisExecutionEnvironment implements EngineExecutionEnvironment { + private final Engine engine; + + IrisExecutionEnvironment(Engine engine) + { + this.engine = engine; + } +} diff --git a/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java b/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java new file mode 100644 index 000000000..91538ff60 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java @@ -0,0 +1,31 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.scripting; + +import com.volmit.iris.engine.framework.Engine; + +public interface EngineExecutionEnvironment +{ + Engine getEngine(); + + default void close() + { + + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/BSFDeclaredBean.java b/src/main/java/com/volmit/iris/util/bsf/BSFDeclaredBean.java new file mode 100644 index 000000000..f68a98435 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/BSFDeclaredBean.java @@ -0,0 +1,39 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.bsf; + +/** + * BSFDeclaredBeans are used internally by BSF to encapsulate information being + * passed between a BSFManager and its various BSFEngines. Note that the + * constructor is not public because this is not a public class. + * + * @author Matthew J. Duftler + * @author Sanjiva Weerawarana + */ +public class BSFDeclaredBean { + public String name; + public Object bean; + public Class type; + + BSFDeclaredBean(String name, Object bean, Class type) { + this.name = name; + this.bean = bean; + this.type = type; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/BSFEngine.java b/src/main/java/com/volmit/iris/util/bsf/BSFEngine.java new file mode 100644 index 000000000..6a3b7247d --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/BSFEngine.java @@ -0,0 +1,253 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.bsf; + +import java.beans.PropertyChangeListener; +import java.util.Vector; + +import com.volmit.iris.util.bsf.util.CodeBuffer; + +/** + * This is the view of a scripting engine assumed by the Bean Scripting + * Framework. This interface is used when an application decides to + * run some script under application control. (This is the reverse of + * the more common situation, which is that of the scripting language + * calling into the application.) + *

+ * When a scripting engine is first fired up, the initialize() + * method is called right after construction. + *

+ * A scripting engine must provide two access points for applications + * to call into them: via function calls and via expression evaluation. + * It must also support loading scripts. + *

+ * A scripting engine is a property change listener and will be notified + * when any of the relevant properties of the manager change. (See + * BSFManager to see which of its properties are bound.) + * + * @author Sanjiva Weerawarana + * @author Matthew J. Duftler + */ +public interface BSFEngine extends PropertyChangeListener { + + /** + * This is used by an application to invoke an anonymous function. An + * anonymous function is a multi-line script which when evaluated will + * produce a value. These are separated from expressions and scripts + * because the prior are spsed to be good 'ol expressions and scripts + * are not value returning. We allow anonymous functions to have parameters + * as well for completeness. + * + * @param source (context info) the source of this expression + * (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param funcBody the multi-line, value returning script to evaluate + * @param paramNames the names of the parameters above assumes + * @param arguments values of the above parameters + * + * @exception BSFException if anything goes wrong while doin' it. + */ + public Object apply( + String source, + int lineNo, + int columnNo, + Object funcBody, + Vector paramNames, + Vector arguments) + throws BSFException; + /** + * This is used by an application to call into the scripting engine + * to make a function/method call. The "object" argument is the object + * whose method is to be called, if that applies. For non-OO languages, + * this is typically ignored and should be given as null. For pretend-OO + * languages such as VB, this would be the (String) name of the object. + * The arguments are given in the args array. + * + * @param object object on which to make the call + * @param name name of the method / procedure to call + * @param args the arguments to be given to the procedure + * + * @exception BSFException if anything goes wrong while eval'ing a + * BSFException is thrown. The reason indicates the problem. + */ + public Object call(Object object, String name, Object[] args) + throws BSFException; + /** + * This is used by an application to compile an anonymous function. See + * comments in apply for more hdetails. + * + * @param source (context info) the source of this expression + * (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param funcBody the multi-line, value returning script to evaluate + * @param paramNames the names of the parameters above assumes + * @param arguments values of the above parameters + * @param cb the CodeBuffer to compile into + * + * @exception BSFException if anything goes wrong while doin' it. + */ + public void compileApply( + String source, + int lineNo, + int columnNo, + Object funcBody, + Vector paramNames, + Vector arguments, + CodeBuffer cb) + throws BSFException; + /** + * This is used by an application to compile a value-returning expression. + * The expr may be string or some other type, depending on the language. + * The generated code is dumped into the CodeBuffer. + * + * @param source (context info) the source of this expression + * (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param expr the expression to compile + * @param cb the CodeBuffer to compile into + * + * @exception BSFException if anything goes wrong while compiling a + * BSFException is thrown. The reason indicates the problem. + */ + public void compileExpr( + String source, + int lineNo, + int columnNo, + Object expr, + CodeBuffer cb) + throws BSFException; + /** + * This is used by an application to compile some script. The + * script may be string or some other type, depending on the + * language. The generated code is dumped into the CodeBuffer. + * + * @param source (context info) the source of this script + * (e.g., filename) + * @param lineNo (context info) the line number in source for script + * @param columnNo (context info) the column number in source for script + * @param script the script to compile + * @param cb the CodeBuffer to compile into + * + * @exception BSFException if anything goes wrong while compiling a + * BSFException is thrown. The reason indicates the problem. + */ + public void compileScript( + String source, + int lineNo, + int columnNo, + Object script, + CodeBuffer cb) + throws BSFException; + /** + * Declare a bean after the engine has been started. Declared beans + * are beans that are named and which the engine must make available + * to the scripts it runs in the most first class way possible. + * + * @param bean the bean to declare + * + * @exception BSFException if the engine cannot do this operation + */ + public void declareBean(BSFDeclaredBean bean) throws BSFException; + /** + * This is used by an application to evaluate an expression. The + * expression may be string or some other type, depending on the + * language. (For example, for BML it'll be an org.w3c.dom.Element + * object.) + * + * @param source (context info) the source of this expression + * (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param expr the expression to evaluate + * + * @exception BSFException if anything goes wrong while eval'ing a + * BSFException is thrown. The reason indicates the problem. + */ + public Object eval(String source, int lineNo, int columnNo, Object expr) + throws BSFException; + /** + * This is used by an application to execute some script. The + * expression may be string or some other type, depending on the + * language. Returns nothing but if something goes wrong it excepts + * (of course). + * + * @param source (context info) the source of this expression + * (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param script the script to execute + * + * @exception BSFException if anything goes wrong while exec'ing a + * BSFException is thrown. The reason indicates the problem. + */ + public void exec(String source, int lineNo, int columnNo, Object script) + throws BSFException; + /** + * This is used by an application to execute some script, as though + * one were interacting with the language in an interactive session. + * The expression may be string or some other type, depending on the + * language. Returns nothing but if something goes wrong it excepts (of + * course). + * + * @param source (context info) the source of this expression + * (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param script the script to execute + * + * @exception BSFException if anything goes wrong while exec'ing a + * BSFException is thrown. The reason indicates the problem. + */ + public void iexec(String source, int lineNo, int columnNo, Object script) + throws BSFException; + + /** + * This method is used to initialize the engine right after construction. + * This method will be called before any calls to eval or call. At this + * time the engine should capture the current values of interesting + * properties from the manager. In the future, any changes to those + * will be mirrored to me by the manager via a property change event. + * + * @param mgr The BSFManager that's hosting this engine. + * @param lang Language string which this engine is handling. + * @param declaredBeans Vector of BSFDeclaredObject containing beans + * that should be declared into the language runtime at init + * time as best as possible. + * + * @exception BSFException if anything goes wrong while init'ing a + * BSFException is thrown. The reason indicates the problem. + */ + public void initialize(BSFManager mgr, String lang, Vector declaredBeans) + throws BSFException; + /** + * Graceful termination + */ + public void terminate(); + /** + * Undeclare a previously declared bean. + * + * @param bean the bean to undeclare + * + * @exception BSFException if the engine cannot do this operation + */ + public void undeclareBean(BSFDeclaredBean bean) throws BSFException; +} diff --git a/src/main/java/com/volmit/iris/util/bsf/BSFException.java b/src/main/java/com/volmit/iris/util/bsf/BSFException.java new file mode 100644 index 000000000..2ab480d05 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/BSFException.java @@ -0,0 +1,71 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.bsf; + +/** + * If something goes wrong while doing some scripting stuff, one of these + * is thrown. The integer code indicates what's wrong and the message + * may give more details. The reason one exception with multiple meanings + * (via the code) [instead of multiple exception types] is used is due to + * the interest to keep the run-time size small. + * + * @author Sanjiva Weerawarana + */ +public class BSFException extends Exception { + public static final int REASON_INVALID_ARGUMENT = 0; + public static final int REASON_IO_ERROR = 10; + public static final int REASON_UNKNOWN_LANGUAGE = 20; + public static final int REASON_EXECUTION_ERROR = 100; + public static final int REASON_UNSUPPORTED_FEATURE = 499; + public static final int REASON_OTHER_ERROR = 500; + + int reason; + Throwable targetThrowable; + + public BSFException (int reason, String msg) { + super (msg); + this.reason = reason; + } + public BSFException (int reason, String msg, Throwable t) { + this (reason, msg); + targetThrowable = t; + } + public BSFException (String msg) { + this (REASON_OTHER_ERROR, msg); + } + public int getReason () { + return reason; + } + public Throwable getTargetException () { + return targetThrowable; + } + public void printStackTrace () { + if (targetThrowable != null) { + String msg = getMessage (); + + if (msg != null && !msg.equals (targetThrowable.getMessage ())) { + System.err.print (msg + ": "); + } + + targetThrowable.printStackTrace (); + } else { + super.printStackTrace (); + } + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/BSFManager.java b/src/main/java/com/volmit/iris/util/bsf/BSFManager.java new file mode 100644 index 000000000..67179a07a --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/BSFManager.java @@ -0,0 +1,913 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.bsf; + +import java.beans.PropertyChangeSupport; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.MissingResourceException; +import java.util.NoSuchElementException; +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.Vector; + +import com.volmit.iris.util.bsf.util.CodeBuffer; +import com.volmit.iris.util.bsf.util.ObjectRegistry; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This class is the entry point to the bean scripting framework. An + * application wishing to integrate scripting to a Java app would + * place an instance of a BSFManager in their code and use its services + * to register the beans they want to make available for scripting, + * load scripting engines, and run scripts. + *

+ * BSFManager serves as the registry of available scripting engines + * as well. Loading and unloading of scripting engines is + * supported as well. Each BSFManager loads one engine per language. + * Several BSFManagers can be created per JVM. + * + * @author Sanjiva Weerawarana + * @author Matthew J. Duftler + * @author Sam Ruby + * @author Olivier Gruber (added original debugging support) + * @author Don Schwarz (added support for registering languages dynamically) + */ +public class BSFManager { + // version string is in the form "abc.yyyymmdd" where + // "abc" represents a dewey decimal number (three levels, each between 0 and 9), + // and "yyyy" a four digit year, "mm" a two digit month, "dd" a two digit day. + // + // Example: "240.20060925" stands for: BSF version "2.4.0" as of "2006-09-25" + protected static String version="240.20061006"; + + // table of registered scripting engines + protected static Hashtable registeredEngines = new Hashtable(); + + // mapping of file extensions to languages + protected static Hashtable extn2Lang = new Hashtable(); + + // table of scripting engine instances created by this manager. + // only one instance of a given language engine is created by a single + // manager instance. + protected Hashtable loadedEngines = new Hashtable(); + + // table of registered beans for use by scripting engines. + protected ObjectRegistry objectRegistry = new ObjectRegistry(); + + // prop change support containing loaded engines to inform when any + // of my interesting properties change + protected PropertyChangeSupport pcs; + + // the class loader to use if a class loader is needed. Default is + // he who loaded me (which may be null in which case its Class.forName). + // protected ClassLoader classLoader = getClass().getClassLoader(); + protected ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // rgf, 2006-01-05 + + // temporary directory to use to dump temporary files into. Note that + // if class files are dropped here then unless this dir is in the + // classpath or unless the classloader knows to look here, the classes + // will not be found. + protected String tempDir = "."; + + // classpath used by those that need a classpath + protected String classPath; + + // stores BSFDeclaredBeans representing objects + // introduced by a client of BSFManager + protected Vector declaredBeans = new Vector(); + + private Log logger = LogFactory.getLog(this.getClass().getName()); + + ////////////////////////////////////////////////////////////////////// + // + // pre-register engines that BSF supports off the shelf + // + ////////////////////////////////////////////////////////////////////// + + static { + try { + Enumeration e = BSFManager.class.getClassLoader().getResources("org/apache/bsf/Languages.properties"); + while (e.hasMoreElements()) { + URL url = (URL)e.nextElement(); + InputStream is = url.openStream(); + + Properties p = new Properties(); + p.load(is); + + for (Enumeration keys = p.propertyNames(); keys.hasMoreElements();) { + + String key = (String) keys.nextElement(); + String value = p.getProperty(key); + String className = value.substring(0, value.indexOf(",")); + + + + + // get the extensions for this language + String exts = value.substring(value.indexOf(",")+1, value.length()); + StringTokenizer st = new StringTokenizer(exts, "|"); + String[] extensions = new String[st.countTokens()]; + for (int i = 0; st.hasMoreTokens(); i++) { + extensions[i] = ((String) st.nextToken()).trim(); + } + + registerScriptingEngine(key, className, extensions); + } + } + } catch (IOException ex) { + + ex.printStackTrace(); + System.err.println("Error reading Languages file " + ex); + } catch (NoSuchElementException nsee) { + + nsee.printStackTrace(); + System.err.println("Syntax error in Languages resource bundle"); + } catch (MissingResourceException mre) { + + mre.printStackTrace(); + System.err.println("Initialization error: " + mre.toString()); + } + } + + public BSFManager() { + pcs = new PropertyChangeSupport(this); + } + + + /** Returns the version string of BSF. + * + * @return version string in the form "abc.yyyymmdd" where + "abc" represents a dewey decimal number (three levels, each between 0 and 9), and + "yyyy" a four digit year, "mm" a two digit month, + "dd" a two digit day. + * +
Example: "240.20061006" + stands for: BSF version 2.4.0 as of 2006-10-06. + * + * + * @since 2006-01-17 + */ + public static String getVersion() { + + return version; + } + + /** + * Apply the given anonymous function of the given language to the given + * parameters and return the resulting value. + * + * @param lang language identifier + * @param source (context info) the source of this expression + (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param funcBody the multi-line, value returning script to evaluate + * @param paramNames the names of the parameters above assumes + * @param arguments values of the above parameters + * + * @exception BSFException if anything goes wrong while running the script + */ + public Object apply(String lang, + String source, + int lineNo, + int columnNo, + Object funcBody, + Vector paramNames, + Vector arguments) + throws BSFException { + logger.debug("BSFManager:apply"); + + final BSFEngine e = loadScriptingEngine(lang); + final String sourcef = source; + final int lineNof = lineNo, columnNof = columnNo; + final Object funcBodyf = funcBody; + final Vector paramNamesf = paramNames; + final Vector argumentsf = arguments; + Object result = null; + + try { + final Object resultf = + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + return e.apply(sourcef, lineNof, columnNof, + funcBodyf, paramNamesf, argumentsf); + } + }); + result = resultf; + } catch (PrivilegedActionException prive) { + + logger.error("Exception: ", prive); + throw (BSFException) prive.getException(); + } + + return result; + } + + /** + * Compile the application of the given anonymous function of the given + * language to the given parameters into the given CodeBuffer. + * + * @param lang language identifier + * @param source (context info) the source of this expression + (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param funcBody the multi-line, value returning script to evaluate + * @param paramNames the names of the parameters above assumes + * @param arguments values of the above parameters + * @param cb code buffer to compile into + * + * @exception BSFException if anything goes wrong while running the script + */ + public void compileApply(String lang, + String source, + int lineNo, + int columnNo, + Object funcBody, + Vector paramNames, + Vector arguments, + CodeBuffer cb) + throws BSFException { + logger.debug("BSFManager:compileApply"); + + final BSFEngine e = loadScriptingEngine(lang); + final String sourcef = source; + final int lineNof = lineNo, columnNof = columnNo; + final Object funcBodyf = funcBody; + final Vector paramNamesf = paramNames; + final Vector argumentsf = arguments; + final CodeBuffer cbf = cb; + + try { + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + e.compileApply(sourcef, lineNof, columnNof, + funcBodyf, paramNamesf, + argumentsf, cbf); + return null; + } + }); + } catch (PrivilegedActionException prive) { + + logger.error("Exception :", prive); + throw (BSFException) prive.getException(); + } + } + + /** + * Compile the given expression of the given language into the given + * CodeBuffer. + * + * @param lang language identifier + * @param source (context info) the source of this expression + (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param expr the expression to compile + * @param cb code buffer to compile into + * + * @exception BSFException if any error while compiling the expression + */ + public void compileExpr(String lang, + String source, + int lineNo, + int columnNo, + Object expr, + CodeBuffer cb) + throws BSFException { + logger.debug("BSFManager:compileExpr"); + + final BSFEngine e = loadScriptingEngine(lang); + final String sourcef = source; + final int lineNof = lineNo, columnNof = columnNo; + final Object exprf = expr; + final CodeBuffer cbf = cb; + + try { + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + e.compileExpr(sourcef, lineNof, columnNof, exprf, cbf); + return null; + } + }); + } catch (PrivilegedActionException prive) { + + logger.error("Exception :", prive); + throw (BSFException) prive.getException(); + } + } + + /** + * Compile the given script of the given language into the given + * CodeBuffer. + * + * @param lang language identifier + * @param source (context info) the source of this script + (e.g., filename) + * @param lineNo (context info) the line number in source for script + * @param columnNo (context info) the column number in source for script + * @param script the script to compile + * @param cb code buffer to compile into + * + * @exception BSFException if any error while compiling the script + */ + public void compileScript(String lang, + String source, + int lineNo, + int columnNo, + Object script, + CodeBuffer cb) + throws BSFException { + logger.debug("BSFManager:compileScript"); + + final BSFEngine e = loadScriptingEngine(lang); + final String sourcef = source; + final int lineNof = lineNo, columnNof = columnNo; + final Object scriptf = script; + final CodeBuffer cbf = cb; + + try { + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + e.compileScript(sourcef, lineNof, columnNof, + scriptf, cbf); + return null; + } + }); + } catch (PrivilegedActionException prive) { + + logger.error("Exception :", prive); + throw (BSFException) prive.getException(); + } + } + + /** + * Declare a bean. The difference between declaring and registering + * is that engines are spsed to make declared beans "pre-available" + * in the scripts as far as possible. That is, if a script author + * needs a registered bean, he needs to look it up in some way. However + * if he needs a declared bean, the language has the responsibility to + * make those beans avaialable "automatically." + *

+ * When a bean is declared it is automatically registered as well + * so that any declared bean can be gotton to by looking it up as well. + *

+ * If any of the languages that are already running in this manager + * says they don't like this (by throwing an exception) then this + * method will simply quit with that exception. That is, any engines + * that come after than in the engine enumeration will not even be + * told about this new bean. + *

+ * So, in general its best to declare beans before the manager has + * been asked to load any engines because then the user can be informed + * when an engine rejects it. Also, its much more likely that an engine + * can declare a bean at start time than it can at any time. + * + * @param beanName name to declare bean as + * @param bean the bean that's being declared + * @param type the type to represent the bean as + * + * @exception BSFException if any of the languages that are already + * running decides to throw an exception when asked to + * declare this bean. + */ + public void declareBean(String beanName, Object bean, Class type) + throws BSFException { + logger.debug("BSFManager:declareBean"); + + registerBean(beanName, bean); + + BSFDeclaredBean tempBean = new BSFDeclaredBean(beanName, bean, type); + declaredBeans.addElement(tempBean); + + Enumeration enginesEnum = loadedEngines.elements(); + BSFEngine engine; + while (enginesEnum.hasMoreElements()) { + engine = (BSFEngine) enginesEnum.nextElement(); + engine.declareBean(tempBean); + } + } + + /** + * Evaluate the given expression of the given language and return the + * resulting value. + * + * @param lang language identifier + * @param source (context info) the source of this expression + (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param expr the expression to evaluate + * + * @exception BSFException if anything goes wrong while running the script + */ + public Object eval(String lang, + String source, + int lineNo, + int columnNo, + Object expr) + throws BSFException { + logger.debug("BSFManager:eval"); + + final BSFEngine e = loadScriptingEngine(lang); + final String sourcef = source; + final int lineNof = lineNo, columnNof = columnNo; + final Object exprf = expr; + Object result = null; + + try { + final Object resultf = + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + return e.eval(sourcef, lineNof, columnNof, exprf); + } + }); + result = resultf; + } catch (PrivilegedActionException prive) { + + logger.error("Exception: ", prive); + throw (BSFException) prive.getException(); + } + + return result; + } + + ////////////////////////////////////////////////////////////////////// + // + // Convenience functions for exec'ing and eval'ing scripts directly + // without loading and dealing with engines etc.. + // + ////////////////////////////////////////////////////////////////////// + + /** + * Execute the given script of the given language. + * + * @param lang language identifier + * @param source (context info) the source of this expression + (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param script the script to execute + * + * @exception BSFException if anything goes wrong while running the script + */ + public void exec(String lang, + String source, + int lineNo, + int columnNo, + Object script) + throws BSFException { + logger.debug("BSFManager:exec"); + + final BSFEngine e = loadScriptingEngine(lang); + final String sourcef = source; + final int lineNof = lineNo, columnNof = columnNo; + final Object scriptf = script; + + try { + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + e.exec(sourcef, lineNof, columnNof, scriptf); + return null; + } + }); + } catch (PrivilegedActionException prive) { + + logger.error("Exception :", prive); + throw (BSFException) prive.getException(); + } + } + + /** + * Execute the given script of the given language, attempting to + * emulate an interactive session w/ the language. + * + * @param lang language identifier + * @param source (context info) the source of this expression + * (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param script the script to execute + * + * @exception BSFException if anything goes wrong while running the script + */ + public void iexec(String lang, + String source, + int lineNo, + int columnNo, + Object script) + throws BSFException { + logger.debug("BSFManager:iexec"); + + final BSFEngine e = loadScriptingEngine(lang); + final String sourcef = source; + final int lineNof = lineNo, columnNof = columnNo; + final Object scriptf = script; + + try { + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + e.iexec(sourcef, lineNof, columnNof, scriptf); + return null; + } + }); + } catch (PrivilegedActionException prive) { + + logger.error("Exception :", prive); + throw (BSFException) prive.getException(); + } + } + + /** + * Get classLoader + */ + public ClassLoader getClassLoader() { + logger.debug("BSFManager:getClassLoader"); + return classLoader; + } + + /** + * Get classPath + */ + public String getClassPath() { + logger.debug("BSFManager:getClassPath"); + if (classPath == null) { + try { + classPath = System.getProperty("java.class.path"); + } catch (Throwable t) { + + logger.debug("Exception :", t); + // prolly a security exception .. so no can do + } + } + return classPath; + } + + /** + * Determine the language of a script file by looking at the file + * extension. + * + * @param fileName the name of the file + * + * @return the scripting language the file is in if the file extension + * is known to me (must have been registered via + * registerScriptingEngine). + * + * @exception BSFException if file's extension is unknown. + */ + public static String getLangFromFilename(String fileName) + throws BSFException { + int dotIndex = fileName.lastIndexOf("."); + + if (dotIndex != -1) { + String extn = fileName.substring(dotIndex + 1); + String langval = (String) extn2Lang.get(extn); + String lang = null; + int index, loops = 0; + + if (langval != null) { + while ((index = langval.indexOf(":", 0)) != -1) { + // Great. Multiple language engines registered + // for this extension. + // Try to find first one that is in our classpath. + lang = langval.substring(0, index); + langval = langval.substring(index + 1); + loops++; + + // Test to see if in classpath + try { + String engineName = + (String) registeredEngines.get(lang); + Class.forName(engineName); + } catch (ClassNotFoundException cnfe) { + + // Bummer. + lang = langval; + continue; + } + + // Got past that? Good. + break; + } + if (loops == 0) { lang = langval; } + } + + if (lang != null && lang != "") { + return lang; + } + } + throw new BSFException(BSFException.REASON_OTHER_ERROR, + "file extension missing or unknown: " + + "unable to determine language for '" + + fileName + + "'"); + } + + /** + * Return the current object registry of the manager. + * + * @return the current registry. + */ + public ObjectRegistry getObjectRegistry() { + return objectRegistry; + } + + /** + * Get tempDir + */ + public String getTempDir() { + return tempDir; + } + + /** + * Determine whether a language is registered. + * + * @param lang string identifying a language + * + * @return true iff it is + */ + public static boolean isLanguageRegistered(String lang) { + return (registeredEngines.get(lang) != null); + } + + ////////////////////////////////////////////////////////////////////// + // + // Bean scripting framework services + // + ////////////////////////////////////////////////////////////////////// + + /** + * Load a scripting engine based on the lang string identifying it. + * + * @param lang string identifying language + * @exception BSFException if the language is unknown (i.e., if it + * has not been registered) with a reason of + * REASON_UNKNOWN_LANGUAGE. If the language is known but + * if the interface can't be created for some reason, then + * the reason is set to REASON_OTHER_ERROR and the actual + * exception is passed on as well. + */ + public BSFEngine loadScriptingEngine(String lang) throws BSFException { + logger.debug("BSFManager:loadScriptingEngine"); + + // if its already loaded return that + BSFEngine eng = (BSFEngine) loadedEngines.get(lang); + if (eng != null) { + return eng; + } + + // is it a registered language? + String engineClassName = (String) registeredEngines.get(lang); + if (engineClassName == null) { + logger.error("unsupported language: " + lang); + throw new BSFException(BSFException.REASON_UNKNOWN_LANGUAGE, + "unsupported language: " + lang); + } + + // create the engine and initialize it. if anything goes wrong + // except. + try { + Class engineClass = + (classLoader == null) + ? Class.forName(engineClassName) + : classLoader.loadClass(engineClassName); + final BSFEngine engf = (BSFEngine) engineClass.newInstance(); + final BSFManager thisf = this; + final String langf = lang; + final Vector dbf = declaredBeans; + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + engf.initialize(thisf, langf, dbf); + return null; + } + }); + eng = engf; + loadedEngines.put(lang, eng); + pcs.addPropertyChangeListener(eng); + return eng; + } catch (PrivilegedActionException prive) { + + logger.error("Exception :", prive); + throw (BSFException) prive.getException(); + } catch (Throwable t) { + + logger.error("Exception :", t); + throw new BSFException(BSFException.REASON_OTHER_ERROR, + "unable to load language: " + lang, + t); + } + } + + /** + * return a handle to a bean registered in the bean registry by the + * application or a scripting engine. Returns null if bean is not found. + * + * @param beanName name of bean to look up + * + * @return the bean if its found or null + */ + public Object lookupBean(String beanName) { + logger.debug("BSFManager:lookupBean"); + + try { + return ((BSFDeclaredBean)objectRegistry.lookup(beanName)).bean; + } catch (IllegalArgumentException e) { + + logger.debug("Exception :", e); + return null; + } + } + + /** + * Registering a bean allows a scripting engine or the application to + * access that bean by name and to manipulate it. + * + * @param beanName name to register under + * @param bean the bean to register + */ + public void registerBean(String beanName, Object bean) { + logger.debug("BSFManager:registerBean"); + + BSFDeclaredBean tempBean; + + if(bean == null) { + tempBean = new BSFDeclaredBean(beanName, null, null); + } else { + + tempBean = new BSFDeclaredBean(beanName, bean, bean.getClass()); + } + objectRegistry.register(beanName, tempBean); + } + + /** + * Register a scripting engine in the static registry of the + * BSFManager. + * + * @param lang string identifying language + * @param engineClassName fully qualified name of the class interfacing + * the language to BSF. + * @param extensions array of file extensions that should be mapped to + * this language type. may be null. + */ + public static void registerScriptingEngine(String lang, + String engineClassName, + String[] extensions) { + registeredEngines.put(lang, engineClassName); + if (extensions != null) { + for (int i = 0; i < extensions.length; i++) { + String langstr = (String) extn2Lang.get(extensions[i]); + langstr = (langstr == null) ? lang : lang + ":" + langstr; + extn2Lang.put(extensions[i], langstr); + } + } + } + + /** + * Set the class loader for those that need to use it. Default is he + * who loaded me or null (i.e., its Class.forName). + * + * @param classLoader the class loader to use. + */ + public void setClassLoader(ClassLoader classLoader) { + logger.debug("BSFManager:setClassLoader"); + + pcs.firePropertyChange("classLoader", this.classLoader, classLoader); + this.classLoader = classLoader; + } + + /** + * Set the classpath for those that need to use it. Default is the value + * of the java.class.path property. + * + * @param classPath the classpath to use + */ + public void setClassPath(String classPath) { + logger.debug("BSFManager:setClassPath"); + + pcs.firePropertyChange("classPath", this.classPath, classPath); + this.classPath = classPath; + } + + /** + * Set the object registry used by this manager. By default a new + * one is created when the manager is new'ed and this overwrites + * that one. + * + * @param objectRegistry the registry to use + */ + public void setObjectRegistry(ObjectRegistry objectRegistry) { + logger.debug("BSFManager:setObjectRegistry"); + + this.objectRegistry = objectRegistry; + } + + /** + * Temporary directory to put stuff into (for those who need to). Note + * that unless this directory is in the classpath or unless the + * classloader knows to look in here, any classes here will not + * be found! BSFManager provides a service method to load a class + * which uses either the classLoader provided by the class loader + * property or, if that fails, a class loader which knows to load from + * the tempdir to try to load the class. Default value of tempDir + * is "." (current working dir). + * + * @param tempDir the temporary directory + */ + public void setTempDir(String tempDir) { + logger.debug("BSFManager:setTempDir"); + + pcs.firePropertyChange("tempDir", this.tempDir, tempDir); + this.tempDir = tempDir; + } + + /** + * Gracefully terminate all engines + */ + public void terminate() { + logger.debug("BSFManager:terminate"); + + Enumeration enginesEnum = loadedEngines.elements(); + BSFEngine engine; + while (enginesEnum.hasMoreElements()) { + engine = (BSFEngine) enginesEnum.nextElement(); + engine.terminate(); + } + + loadedEngines = new Hashtable(); + } + + /** + * Undeclare a previously declared bean. This removes the bean from + * the list of declared beans in the manager as well as asks every + * running engine to undeclared the bean. As with above, if any + * of the engines except when asked to undeclare, this method does + * not catch that exception. Quietly returns if the bean is unknown. + * + * @param beanName name of bean to undeclare + * + * @exception BSFException if any of the languages that are already + * running decides to throw an exception when asked to + * undeclare this bean. + */ + public void undeclareBean(String beanName) throws BSFException { + logger.debug("BSFManager:undeclareBean"); + + unregisterBean(beanName); + + BSFDeclaredBean tempBean = null; + boolean found = false; + for (Iterator i = declaredBeans.iterator(); i.hasNext();) { + tempBean = (BSFDeclaredBean) i.next(); + if (tempBean.name.equals(beanName)) { + found = true; + break; + } + } + + if (found) { + declaredBeans.removeElement(tempBean); + + Enumeration enginesEnum = loadedEngines.elements(); + while (enginesEnum.hasMoreElements()) { + BSFEngine engine = (BSFEngine) enginesEnum.nextElement(); + engine.undeclareBean(tempBean); + } + } + } + + /** + * Unregister a previously registered bean. Silent if name is not found. + * + * @param beanName name of bean to unregister + */ + public void unregisterBean(String beanName) { + logger.debug("BSFManager:unregisterBean"); + + objectRegistry.unregister(beanName); + } +} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/bsf/Languages.properties b/src/main/java/com/volmit/iris/util/bsf/Languages.properties new file mode 100644 index 000000000..6c5e83281 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/Languages.properties @@ -0,0 +1,50 @@ +# +# Iris is a World Generator for Minecraft Bukkit Servers +# Copyright (c) 2021 Arcane Arts (Volmit Software) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# List of script types and their associated scripting engines +# +# languageDescriptor = engineClass, ext1|ext2|... {, codebaseURL, ...} +# +# where exti are extensions for the language. Note that we leave +# all the engines enabled now and allow them to fail at load time. +# This way engines can be added by just adding to the classpath +# without having to edit this file. Cheating, really, but it works. +# +javascript = com.volmit.iris.util.bsf.engines.javascript.JavaScriptEngine, js +jacl = com.volmit.iris.util.bsf.engines.jacl.JaclEngine, jacl +netrexx = com.volmit.iris.util.bsf.engines.netrexx.NetRexxEngine, nrx +java = com.volmit.iris.util.bsf.engines.java.JavaEngine, java +javaclass = com.volmit.iris.util.bsf.engines.javaclass.JavaClassEngine, class +bml = org.apache.bml.ext.BMLEngine, bml +vbscript = com.volmit.iris.util.bsf.engines.activescript.ActiveScriptEngine, vbs +jscript = com.volmit.iris.util.bsf.engines.activescript.ActiveScriptEngine, jss +perlscript = com.volmit.iris.util.bsf.engines.activescript.ActiveScriptEngine, pls +perl = com.volmit.iris.util.bsf.engines.perl.PerlEngine, pl +jpython = com.volmit.iris.util.bsf.engines.jpython.JPythonEngine, py +jython = com.volmit.iris.util.bsf.engines.jython.JythonEngine, py +lotusscript = com.volmit.iris.util.bsf.engines.lotusscript.LsEngine, lss +xslt = com.volmit.iris.util.bsf.engines.xslt.XSLTEngine, xslt +pnuts = pnuts.ext.PnutsBSFEngine, pnut +beanbasic = com.volmit.iris.util.bsf.engines.beanbasic.BeanBasicEngine, bb +beanshell = bsh.util.BeanShellBSFEngine, bsh +ruby = org.jruby.javasupport.bsf.JRubyEngine, rb +judoscript = com.judoscript.BSFJudoEngine, judo|jud +groovy = org.codehaus.groovy.bsf.GroovyEngine, groovy|gy +objectscript = oscript.bsf.ObjectScriptEngine, os +prolog = ubc.cs.JLog.Extras.BSF.JLogBSFEngine, plog|prolog +rexx = org.rexxla.bsf.engines.rexx.RexxEngine, rex | rexx | cls | rxj | rxs diff --git a/src/main/java/com/volmit/iris/util/bsf/Main.java b/src/main/java/com/volmit/iris/util/bsf/Main.java new file mode 100644 index 000000000..10fbfe6a6 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/Main.java @@ -0,0 +1,190 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.bsf; + +import java.awt.Frame; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.Reader; +import java.util.Hashtable; + +import com.volmit.iris.util.bsf.util.CodeBuffer; +import com.volmit.iris.util.bsf.util.IOUtils; + +/** + * This is the main driver for BSF to be run on the command line + * to eval/exec/compile scripts directly. + * + * @author Sanjiva Weerawarana + * @author Matthew J. Duftler + * @author Sam Ruby + */ +public class Main { + private static String ARG_IN = "-in"; + private static String ARG_LANG = "-lang"; + private static String ARG_MODE = "-mode"; + private static String ARG_OUT = "-out"; + private static String ARG_VAL_EVAL = "eval"; + private static String ARG_VAL_EXEC = "exec"; + private static String ARG_VAL_COMPILE = "compile"; + private static String DEFAULT_IN_FILE_NAME = ""; + private static String DEFAULT_MODE = ARG_VAL_EVAL; + private static String DEFAULT_CLASS_NAME = "Test"; + + /** + * Static driver to be able to run BSF scripts from the command line. + * + * @param args command line arguments + * + * @exception IOException if any I/O error while loading script + */ + public static void main(String[] args) throws IOException { + try { + if ((args.length == 0) || (args.length % 2 != 0)) { + printHelp(); + System.exit(1); + } + + Hashtable argsTable = new Hashtable(); + + argsTable.put(ARG_OUT, DEFAULT_CLASS_NAME); + argsTable.put(ARG_MODE, DEFAULT_MODE); + + for (int i = 0; i < args.length; i += 2) { + argsTable.put(args[i], args[i + 1]); + } + + String inFileName = (String) argsTable.get(ARG_IN); + String language = (String) argsTable.get(ARG_LANG); + + if (language == null) { + if (inFileName != null) { + language = BSFManager.getLangFromFilename(inFileName); + } else { + throw new BSFException( + BSFException.REASON_OTHER_ERROR, + "unable to determine language"); + } + } + + Reader in; + + if (inFileName != null) { + in = new FileReader(inFileName); + } else { + in = new InputStreamReader(System.in); + inFileName = DEFAULT_IN_FILE_NAME; + } + + BSFManager mgr = new BSFManager(); + String mode = (String) argsTable.get(ARG_MODE); + + if (mode.equals(ARG_VAL_COMPILE)) { + String outClassName = (String) argsTable.get(ARG_OUT); + FileWriter out = new FileWriter(outClassName + ".java"); + PrintWriter pw = new PrintWriter(out); + + CodeBuffer cb = new CodeBuffer(); + cb.setClassName(outClassName); + mgr.compileScript( + language, + inFileName, + 0, + 0, + IOUtils.getStringFromReader(in), + cb); + cb.print(pw, true); + out.close(); + } else { + if (mode.equals(ARG_VAL_EXEC)) { + mgr.exec(language, inFileName, 0, 0, IOUtils.getStringFromReader(in)); + } else { /* eval */ + Object obj = mgr.eval(language, inFileName, 0, 0, IOUtils.getStringFromReader(in)); + + + // Try to display the result. + + if (obj instanceof java.awt.Component) { + Frame f; + if (obj instanceof Frame) { + f = (Frame) obj; + } else { + f = new Frame ("BSF Result: " + inFileName); + f.add ((java.awt.Component) obj); + } + // Add a window listener to quit on closing. + f.addWindowListener( + new WindowAdapter () { + public void windowClosing (WindowEvent e) { + System.exit (0); + } + } + ); + f.pack (); + // f.show(); // javac 1.5 warns to use f.show(), Apache build scripts abort as a result :( + f.setVisible(true); // available since Java 1.1 + } else { + System.err.println("Result: " + obj); + + } + + System.err.println("Result: " + obj); + } + } + } catch (BSFException e) { + e.printStackTrace(); + } + } + + private static void printHelp() { + System.err.println("Usage:"); + System.err.println(); + System.err.println(" java " + Main.class.getName() + " [args]"); + System.err.println(); + System.err.println(" args:"); + System.err.println(); + System.err.println( + " [-in fileName] default: " + DEFAULT_IN_FILE_NAME); + System.err.println( + " [-lang languageName] default: " + + ""); + System.err.println( + " [-mode (eval|exec|compile)] default: " + DEFAULT_MODE); + System.err.println(); + System.err.println( + " Additional args used only if -mode is " + "set to \"compile\":"); + System.err.println(); + System.err.println( + " [-out className] default: " + DEFAULT_CLASS_NAME); + } +} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/jacl/BSFCommand.java b/src/main/java/com/volmit/iris/util/bsf/engines/jacl/BSFCommand.java new file mode 100644 index 000000000..9c1702d35 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/engines/jacl/BSFCommand.java @@ -0,0 +1,107 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.engines.jacl; + +import com.volmit.iris.util.bsf.BSFEngine; +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; +import com.volmit.iris.util.bsf.util.EngineUtils; + +import tcl.lang.Command; +import tcl.lang.Interp; +import tcl.lang.ReflectObject; +import tcl.lang.TCL; +import tcl.lang.TclException; +import tcl.lang.TclObject; + +// class used to add "bsf" command to the Jacl runtime +class BSFCommand implements Command { + BSFManager mgr; + BSFEngine jengine; + + BSFCommand (BSFManager mgr, BSFEngine jengine) { + this.mgr = mgr; + this.jengine = jengine; + } + public void cmdProc (Interp interp, + TclObject argv[]) throws TclException { + if (argv.length < 2) { + interp.setResult ("invalid # of args; usage: bsf " + + "lookupBean|registerBean|unregisterBean|addEventListener args"); + throw new TclException (TCL.ERROR); + } + + String op = argv[1].toString (); + + if (op.equals ("lookupBean")) { + if (argv.length != 3) { + interp.setResult ("invalid # of args; usage: bsf " + + "lookupBean name-of-bean"); + throw new TclException (TCL.ERROR); + } + + String beanName = argv[2].toString (); + Object bean = mgr.lookupBean (beanName); + if (bean == null) { + interp.setResult ("unknown object: " + beanName); + throw new TclException (TCL.ERROR); + } + interp.setResult (ReflectObject.newInstance (interp, bean.getClass (), + bean)); + + } else if (op.equals ("registerBean")) { + if (argv.length != 4) { + interp.setResult ("invalid # of args; usage: bsf " + + "registerBean name-of-bean bean"); + throw new TclException (TCL.ERROR); + } + mgr.registerBean (argv[2].toString (), + ReflectObject.get (interp, argv[3])); + interp.setResult (""); + + } else if (op.equals ("unregisterBean")) { + if (argv.length != 3) { + interp.setResult ("invalid # of args; usage: bsf " + + "unregisterBean name-of-bean"); + throw new TclException (TCL.ERROR); + } + mgr.unregisterBean (argv[2].toString ()); + interp.setResult (""); + + } else if (op.equals ("addEventListener")) { + if (argv.length != 6) { + interp.setResult ("invalid # of args; usage: bsf " + + "addEventListener object event-set-name filter " + + "script-to-run"); + throw new TclException (TCL.ERROR); + } + try { + // usage: bsf addEventListener object event-set filter script + String filter = argv[4].toString (); + filter = filter.equals ("") ? null : filter; + EngineUtils.addEventListener (ReflectObject.get (interp, argv[2]), + argv[3].toString (), filter, + jengine, mgr, "", 0, 0, + argv[5].toString ()); + } catch (BSFException e) { + e.printStackTrace (); + interp.setResult ("got BSF exception: " + e.getMessage ()); + throw new TclException (TCL.ERROR); + } + } + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/jacl/JaclEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/jacl/JaclEngine.java new file mode 100644 index 000000000..57cdfbbf0 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/engines/jacl/JaclEngine.java @@ -0,0 +1,136 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.engines.jacl; + +import java.util.Vector; + +import com.volmit.iris.util.bsf.BSFDeclaredBean; +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; +import com.volmit.iris.util.bsf.util.BSFEngineImpl; + +import tcl.lang.Interp; +import tcl.lang.ReflectObject; +import tcl.lang.TclDouble; +import tcl.lang.TclException; +import tcl.lang.TclInteger; +import tcl.lang.TclObject; +import tcl.lang.TclString; + +/** + * This is the interface to Scriptics's Jacl (Tcl) from the + * Bean Scripting Framework. + *

+ * + * @author Sanjiva Weerawarana + */ + +public class JaclEngine extends BSFEngineImpl { + /* the Jacl interpretor object */ + private Interp interp; + + /** + * + * @param method The name of the method to call. + * @param args an array of arguments to be + * passed to the extension, which may be either + * Vectors of Nodes, or Strings. + */ + public Object call (Object obj, String method, Object[] args) + throws BSFException { + StringBuffer tclScript = new StringBuffer (method); + if (args != null) { + for( int i = 0 ; i < args.length ; i++ ) { + tclScript.append (" "); + tclScript.append (args[i].toString ()); + } + } + return eval ("", 0, 0, tclScript.toString ()); + } + /** + * Declare a bean + */ + public void declareBean (BSFDeclaredBean bean) throws BSFException { + String expr = "set " + bean.name + " [bsf lookupBean \"" + bean.name + + "\"]"; + eval ("", 0, 0, expr); + } + /** + * This is used by an application to evaluate a string containing + * some expression. + */ + public Object eval (String source, int lineNo, int columnNo, + Object oscript) throws BSFException { + String script = oscript.toString (); + try { + interp.eval (script); + TclObject result = interp.getResult(); + Object internalRep = result.getInternalRep(); + + // if the object has a corresponding Java type, unwrap it + if (internalRep instanceof ReflectObject) + return ReflectObject.get(interp,result); + if (internalRep instanceof TclString) + return result.toString(); + if (internalRep instanceof TclDouble) + return new Double(TclDouble.get(interp,result)); + if (internalRep instanceof TclInteger) + return new Integer(TclInteger.get(interp,result)); + + return result; + } catch (TclException e) { + throw new BSFException (BSFException.REASON_EXECUTION_ERROR, + "error while eval'ing Jacl expression: " + + interp.getResult (), e); + } + } + /** + * Initialize the engine. + */ + public void initialize (BSFManager mgr, String lang, + Vector declaredBeans) throws BSFException { + super.initialize (mgr, lang, declaredBeans); + + // create interpreter + interp = new Interp(); + + // register the extension that user's can use to get at objects + // registered by the app + interp.createCommand ("bsf", new BSFCommand (mgr, this)); + + // Make java functions be available to Jacl + try { + interp.eval("jaclloadjava"); + } catch (TclException e) { + throw new BSFException (BSFException.REASON_OTHER_ERROR, + "error while loading java package: " + + interp.getResult (), e); + } + + int size = declaredBeans.size (); + for (int i = 0; i < size; i++) { + declareBean ((BSFDeclaredBean) declaredBeans.elementAt (i)); + } + } + + /** + * Undeclare a previously declared bean. + */ + public void undeclareBean (BSFDeclaredBean bean) throws BSFException { + eval ("", 0, 0, "set " + bean.name + " \"\""); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/java/JavaEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/java/JavaEngine.java new file mode 100644 index 000000000..7b2405449 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/engines/java/JavaEngine.java @@ -0,0 +1,352 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.engines.java; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.lang.reflect.Method; +import java.util.Hashtable; +import java.util.Vector; + +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; +import com.volmit.iris.util.bsf.util.BSFEngineImpl; +import com.volmit.iris.util.bsf.util.CodeBuffer; +import com.volmit.iris.util.bsf.util.EngineUtils; +import com.volmit.iris.util.bsf.util.JavaUtils; +import com.volmit.iris.util.bsf.util.MethodUtils; +import com.volmit.iris.util.bsf.util.ObjInfo; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This is the interface to Java from the + * Bean Scripting Framework. + *

+ * The Java code must be written script-style -- that is, just the body of + * the function, without class or method headers or footers. + * The JavaEngine will generate those via a "boilerplate" wrapper: + *

+ * 
+ * import java.lang.*;
+ * import java.util.*;
+ * public class $$CLASSNAME$$ {
+ *   static public Object BSFJavaEngineEntry(com.volmit.iris.util.bsf.BSFManager bsf) {
+ *     // Your code will be placed here
+ *   }
+ * }
+ * 
+ * 
+ * $$CLASSNAME$$ will be replaced by a generated classname of the form + * BSFJava*, and the bsf parameter can be used to retrieve application + * objects registered with the Bean Scripting Framework. + *

+ * If you use the placeholder string $$CLASSNAME$$ elsewhere + * in your script -- including within text strings -- BSFJavaEngine will + * replace it with the generated name of the class before the Java code + * is compiled. + *

+ *

Hazards:

+ *

+ * NOTE that it is your responsibility to convert the code into an acceptable + * Java string. If you're invoking the JavaEngine directly (as in the + * JSPLikeInJava example) that means \"quoting\" characters that would + * otherwise cause trouble. + *

+ * ALSO NOTE that it is your responsibility to return an object, or null in + * lieu thereof! + *

+ * Since the code has to be compiled to a Java classfile, invoking it involves + * a fair amount of computation to load and execute the compiler. We are + * currently making an attempt to manage that by caching the class + * after it has been loaded, but the indexing is fairly primitive. It has + * been suggested that the Bean Scripting Framework may want to support + * preload-and-name-script and execute-preloaded-script-by-name options to + * provide better control over when and how much overhead occurs. + *

+ * @author Joe Kesselman + */ +public class JavaEngine extends BSFEngineImpl { + Class javaclass = null; + static Hashtable codeToClass = new Hashtable(); + static String serializeCompilation = ""; + static String placeholder = "$$CLASSNAME$$"; + String minorPrefix; + + private Log logger = LogFactory.getLog(this.getClass().getName()); + + /** + * Create a scratchfile, open it for writing, return its name. + * Relies on the filesystem to provide us with uniqueness testing. + * NOTE THAT uniqueFileOffset continues to count; we don't want to + * risk reusing a classname we have previously loaded in this session + * even if the classfile has been deleted. + */ + private int uniqueFileOffset = -1; + + private class GeneratedFile { + File file = null; + FileOutputStream fos = null; + String className = null; + GeneratedFile(File file, FileOutputStream fos, String className) { + this.file = file; + this.fos = fos; + this.className = className; + } + } + + /** + * Constructor. + */ + public JavaEngine () { + // Do compilation-possible check here?????????????? + } + + public Object call (Object object, String method, Object[] args) + throws BSFException + { + throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE, + "call() is not currently supported by JavaEngine"); + } + + public void compileScript (String source, int lineNo, int columnNo, + Object script, CodeBuffer cb) throws BSFException { + ObjInfo oldRet = cb.getFinalServiceMethodStatement (); + + if (oldRet != null && oldRet.isExecutable ()) { + cb.addServiceMethodStatement (oldRet.objName + ";"); + } + + cb.addServiceMethodStatement (script.toString ()); + cb.setFinalServiceMethodStatement (null); + } + + /** + * This is used by an application to evaluate a string containing + * some expression. It should store the "bsf" handle where the + * script can get to it, for callback purposes. + *

+ * Note that Java compilation imposes serious overhead, + * but in exchange you get full Java performance + * once the classes have been created (minus the cache lookup cost). + *

+ * Nobody knows whether javac is threadsafe. + * I'm going to serialize access to protect it. + *

+ * There is no published API for invoking javac as a class. There's a trick + * that seems to work for Java 1.1.x, but it stopped working in Java 1.2. + * We will attempt to use it, then if necessary fall back on invoking + * javac via the command line. + */ + public Object eval (String source, int lineNo, int columnNo, + Object oscript) throws BSFException + { + Object retval = null; + String classname = null; + GeneratedFile gf = null; + + String basescript = oscript.toString(); + String script = basescript; // May be altered by $$CLASSNAME$$ expansion + + try { + // Do we already have a class exactly matching this code? + javaclass = (Class)codeToClass.get(basescript); + + if(javaclass != null) { + classname=javaclass.getName(); + } else { + gf = openUniqueFile(tempDir, "BSFJava",".java"); + if( gf == null) { + throw new BSFException("couldn't create JavaEngine scratchfile"); + } + // Obtain classname + classname = gf.className; + + // Write the kluge header to the file. + gf.fos.write(("import java.lang.*;"+ + "import java.util.*;"+ + "public class "+classname+" {\n" + + " static public Object BSFJavaEngineEntry(com.volmit.iris.util.bsf.BSFManager bsf) {\n") + .getBytes()); + + // Edit the script to replace placeholder with the generated + // classname. Note that this occurs _after_ the cache was checked! + int startpoint = script.indexOf(placeholder); + int endpoint; + if(startpoint >= 0) { + StringBuffer changed = new StringBuffer(); + for(; startpoint >=0; startpoint = script.indexOf(placeholder,startpoint)) { + changed.setLength(0); // Reset for 2nd pass or later + if(startpoint > 0) { + changed.append(script.substring(0,startpoint)); + } + changed.append(classname); + endpoint = startpoint+placeholder.length(); + if(endpoint < script.length()) { + changed.append(script.substring(endpoint)); + } + script = changed.toString(); + } + } + + // MJD - debug +// BSFDeclaredBean tempBean; +// String className; +// +// for (int i = 0; i < declaredBeans.size (); i++) { +// tempBean = (BSFDeclaredBean) declaredBeans.elementAt (i); +// className = StringUtils.getClassName (tempBean.bean.getClass ()); +// +// gf.fos.write ((className + " " + +// tempBean.name + " = (" + className + +// ")bsf.lookupBean(\"" + +// tempBean.name + "\");").getBytes ()); +// } + // MJD - debug + + // Copy the input to the file. + // Assumes all available -- probably mistake, but same as other engines. + gf.fos.write(script.getBytes()); + // Close the method and class + gf.fos.write(("\n }\n}\n").getBytes()); + gf.fos.close(); + + // Compile through Java to .class file + // May not be threadsafe. Serialize access on static object: + synchronized(serializeCompilation) { + JavaUtils.JDKcompile(gf.file.getPath(), classPath); + } + + // Load class. + javaclass = EngineUtils.loadClass(mgr, classname); + + // Stash class for reuse + codeToClass.put(basescript, javaclass); + } + + Object[] callArgs = {mgr}; + retval = internalCall(this,"BSFJavaEngineEntry",callArgs); + } + + + catch(Exception e) { + e.printStackTrace (); + throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage ()); + } finally { + // Cleanup: delete the .java and .class files + +// if(gf!=null && gf.file!=null && gf.file.exists()) +// gf.file.delete(); // .java file + + + if(classname!=null) { + // Generated class + File file = new File(tempDir+File.separatorChar+classname+".class"); +// if(file.exists()) +// file.delete(); + + // Search for and clean up minor classes, classname$xxx.class + file = new File(tempDir); // ***** Is this required? + minorPrefix = classname+"$"; // Indirect arg to filter + String[] minorClassfiles = file.list(new FilenameFilter() + { + // Starts with classname$ and ends with .class + public boolean accept(File dir,String name) { + return + (0 == name.indexOf(minorPrefix)) + && + (name.lastIndexOf(".class") == name.length()-6); + } + }); + for(int i = 0; i < minorClassfiles.length; ++i) { + file = new File(minorClassfiles[i]); +// file.delete(); + } + } + } + return retval; + } + + public void initialize (BSFManager mgr, String lang, + Vector declaredBeans) throws BSFException { + super.initialize (mgr, lang, declaredBeans); + } + /** + * Return an object from an extension. + * @param object Object on which to make the internal_call (ignored). + * @param method The name of the method to internal_call. + * @param args an array of arguments to be + * passed to the extension, which may be either + * Vectors of Nodes, or Strings. + */ + Object internalCall (Object object, String method, Object[] args) + throws BSFException + { + //***** ISSUE: Only static methods are currently supported + Object retval = null; + try { + if(javaclass != null) { + //***** This should call the lookup used in BML, for typesafety + Class[] argtypes = new Class[args.length]; + for(int i=0; i0;--i,++uniqueFileOffset) { + // Probably a timing hazard here... *************** + try { + className = prefix+uniqueFileOffset; + file = new File(directory+File.separatorChar+className+suffix); + if(file != null && !file.exists()) { + fos = new FileOutputStream(file); + } + } + catch(Exception e) { + // File could not be opened for write, or Security Exception + // was thrown. If someone else created the file before we could + // open it, that's probably a threading conflict and we don't + // bother reporting it. + if(!file.exists()) { + logger.error("openUniqueFile: unexpected ", e); + } + } + } + if(fos==null) { + logger.error("openUniqueFile: Failed "+max+"attempts."); + } else { + gf = new GeneratedFile(file,fos,className); + } + return gf; + } +} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/javaclass/JavaClassEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/javaclass/JavaClassEngine.java new file mode 100644 index 000000000..c79007d87 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/engines/javaclass/JavaClassEngine.java @@ -0,0 +1,73 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.engines.javaclass; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.util.BSFEngineImpl; +import com.volmit.iris.util.bsf.util.MethodUtils; + +/** + * This is the interface to scripts consisting of Java objects from the + * Bean Scripting Framework. + * + * @author Sanjiva Weerawarana + */ +public class JavaClassEngine extends BSFEngineImpl { + /** + * call the named method of the given object. If object is an instance + * of Class, then the call is a static call on that object. If not, its + * an instance method call or a static call (as per Java) on the given + * object. + */ + public Object call (Object object, String method, Object[] args) + throws BSFException { + // determine arg types + Class[] argTypes = null; + if (args != null) { + argTypes = new Class[args.length]; + for (int i = 0; i < args.length; i++) { + argTypes[i] = (args[i] != null) ? args[i].getClass () : null; + } + } + + // now find method with the right signature, call it and return result + try { + Method m = MethodUtils.getMethod (object, method, argTypes); + return m.invoke (object, args); + } catch (Exception e) { + // something went wrong while invoking method + Throwable t = (e instanceof InvocationTargetException) ? + ((InvocationTargetException)e).getTargetException () : + null; + throw new BSFException (BSFException.REASON_OTHER_ERROR, + "method invocation failed: " + e + + ((t==null)?"":(" target exception: "+t)), t); + } + } + /** + * This is used by an application to evaluate an object containing + * some expression - clearly not possible for compiled code .. + */ + public Object eval (String source, int lineNo, int columnNo, + Object oscript) throws BSFException { + throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE, + "Java bytecode engine can't evaluate expressions"); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/javascript/JavaScriptEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/javascript/JavaScriptEngine.java new file mode 100644 index 000000000..12051a811 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/engines/javascript/JavaScriptEngine.java @@ -0,0 +1,233 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.engines.javascript; + +import java.util.Iterator; +import java.util.Vector; + +import com.volmit.iris.util.bsf.BSFDeclaredBean; +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; +import com.volmit.iris.util.bsf.util.BSFEngineImpl; +import com.volmit.iris.util.bsf.util.BSFFunctions; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.EvaluatorException; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.ImporterTopLevel; +import org.mozilla.javascript.JavaScriptException; +import org.mozilla.javascript.NativeJavaObject; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.WrappedException; +import org.mozilla.javascript.Wrapper; + +/** + * This is the interface to Netscape's Rhino (JavaScript) from the + * Bean Scripting Framework. + *

+ * The original version of this code was first written by Adam Peller + * for use in LotusXSL. Sanjiva took his code and adapted it for BSF. + * + * @author Adam Peller + * @author Sanjiva Weerawarana + * @author Matthew J. Duftler + * @author Norris Boyd + */ +public class JavaScriptEngine extends BSFEngineImpl { + /** + * The global script object, where all embedded functions are defined, + * as well as the standard ECMA "core" objects. + */ + private Scriptable global; + + /** + * Return an object from an extension. + * @param object Object on which to make the call (ignored). + * @param method The name of the method to call. + * @param args an array of arguments to be + * passed to the extension, which may be either + * Vectors of Nodes, or Strings. + */ + public Object call(Object object, String method, Object[] args) + throws BSFException { + + Object retval = null; + Context cx; + + try { + cx = Context.enter(); + + // REMIND: convert arg list Vectors here? + + Object fun = global.get(method, global); + // NOTE: Source and line arguments are nonsense in a call(). + // Any way to make these arguments *sensible? + if (fun == Scriptable.NOT_FOUND) + throw new EvaluatorException("function " + method + + " not found.", "none", 0); + + cx.setOptimizationLevel(-1); + cx.setGeneratingDebug(false); + cx.setGeneratingSource(false); + cx.setOptimizationLevel(0); + cx.setDebugger(null, null); + + retval = + ((Function) fun).call(cx, global, global, args); + +// ScriptRuntime.call(cx, fun, global, args, global); + + if (retval instanceof Wrapper) + retval = ((Wrapper) retval).unwrap(); + } + catch (Throwable t) { + handleError(t); + } + finally { + Context.exit(); + } + return retval; + } + + public void declareBean(BSFDeclaredBean bean) throws BSFException { + if ((bean.bean instanceof Number) || + (bean.bean instanceof String) || + (bean.bean instanceof Boolean)) { + global.put(bean.name, global, bean.bean); + } + else { + // Must wrap non-scriptable objects before presenting to Rhino + Scriptable wrapped = Context.toObject(bean.bean, global); + global.put(bean.name, global, wrapped); + } + } + + /** + * This is used by an application to evaluate a string containing + * some expression. + */ + public Object eval(String source, int lineNo, int columnNo, Object oscript) + throws BSFException { + + String scriptText = oscript.toString(); + Object retval = null; + Context cx; + + try { + cx = Context.enter(); + + cx.setOptimizationLevel(-1); + cx.setGeneratingDebug(false); + cx.setGeneratingSource(false); + cx.setOptimizationLevel(0); + cx.setDebugger(null, null); + + retval = cx.evaluateString(global, scriptText, + source, lineNo, + null); + + if (retval instanceof NativeJavaObject) + retval = ((NativeJavaObject) retval).unwrap(); + + } + catch (Throwable t) { // includes JavaScriptException, rethrows Errors + handleError(t); + } + finally { + Context.exit(); + } + return retval; + } + + private void handleError(Throwable t) throws BSFException { + if (t instanceof WrappedException) + t = ((WrappedException) t).getWrappedException(); + + String message = null; + Throwable target = t; + + if (t instanceof JavaScriptException) { + message = t.getLocalizedMessage(); + + // Is it an exception wrapped in a JavaScriptException? + Object value = ((JavaScriptException) t).getValue(); + if (value instanceof Throwable) { + // likely a wrapped exception from a LiveConnect call. + // Display its stack trace as a diagnostic + target = (Throwable) value; + } + } + else if (t instanceof EvaluatorException || + t instanceof SecurityException) { + message = t.getLocalizedMessage(); + } + else if (t instanceof RuntimeException) { + message = "Internal Error: " + t.toString(); + } + else if (t instanceof StackOverflowError) { + message = "Stack Overflow"; + } + + if (message == null) + message = t.toString(); + + if (t instanceof Error && !(t instanceof StackOverflowError)) { + // Re-throw Errors because we're supposed to let the JVM see it + // Don't re-throw StackOverflows, because we know we've + // corrected the situation by aborting the loop and + // a long stacktrace would end up on the user's console + throw (Error) t; + } + else { + throw new BSFException(BSFException.REASON_OTHER_ERROR, + "JavaScript Error: " + message, + target); + } + } + + /** + * Initialize the engine. + * Put the manager into the context-manager + * map hashtable too. + */ + public void initialize(BSFManager mgr, String lang, Vector declaredBeans) + throws BSFException { + + super.initialize(mgr, lang, declaredBeans); + + // Initialize context and global scope object + try { + Context cx = Context.enter(); + global = new ImporterTopLevel(cx); + Scriptable bsf = Context.toObject(new BSFFunctions(mgr, this), global); + global.put("bsf", global, bsf); + + for(Iterator it = declaredBeans.iterator(); it.hasNext();) { + declareBean((BSFDeclaredBean) it.next()); + } + } + catch (Throwable t) { + + } + finally { + Context.exit(); + } + } + + public void undeclareBean(BSFDeclaredBean bean) throws BSFException { + global.delete(bean.name); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/jython/JythonEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/jython/JythonEngine.java new file mode 100644 index 000000000..2ed1928b7 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/engines/jython/JythonEngine.java @@ -0,0 +1,244 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.engines.jython; + +import java.io.ByteArrayInputStream; +import java.util.Vector; + +import com.volmit.iris.util.bsf.BSFDeclaredBean; +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; +import com.volmit.iris.util.bsf.util.BSFEngineImpl; +import com.volmit.iris.util.bsf.util.BSFFunctions; +import org.python.core.Py; +import org.python.core.PyException; +import org.python.core.PyJavaInstance; +import org.python.core.PyObject; +import org.python.util.InteractiveInterpreter; + +/** + * This is the interface to Jython (http://www.jython.org/) from BSF. + * It's derived from the JPython 1.x engine + * + * @author Sanjiva Weerawarana + * @author Finn Bock + * @author Chuck Murcko + */ + +public class JythonEngine extends BSFEngineImpl { + BSFPythonInterpreter interp; + + /** + * call the named method of the given object. + */ + public Object call (Object object, String method, Object[] args) + throws BSFException { + try { + PyObject[] pyargs = Py.EmptyObjects; + + if (args != null) { + pyargs = new PyObject[args.length]; + for (int i = 0; i < pyargs.length; i++) + pyargs[i] = Py.java2py(args[i]); + } + + if (object != null) { + PyObject o = Py.java2py(object); + return unwrap(o.invoke(method, pyargs)); + } + + PyObject m = interp.get(method); + + if (m == null) + m = interp.eval(method); + if (m != null) { + return unwrap(m.__call__(pyargs)); + } + + return null; + } catch (PyException e) { + throw new BSFException (BSFException.REASON_EXECUTION_ERROR, + "exception from Jython:\n" + e, e); + } + } + + /** + * Declare a bean + */ + public void declareBean (BSFDeclaredBean bean) throws BSFException { + interp.set (bean.name, bean.bean); + } + + /** + * Evaluate an anonymous function (differs from eval() in that apply() + * handles multiple lines). + */ + public Object apply (String source, int lineNo, int columnNo, + Object funcBody, Vector paramNames, + Vector arguments) throws BSFException { + try { + /* We wrapper the original script in a function definition, and + * evaluate the function. A hack, no question, but it allows + * apply() to pretend to work on Jython. + */ + StringBuffer script = new StringBuffer(byteify(funcBody.toString())); + int index = 0; + script.insert(0, "def bsf_temp_fn():\n"); + + while (index < script.length()) { + if (script.charAt(index) == '\n') { + script.insert(index+1, '\t'); + } + index++; + } + + interp.exec (script.toString ()); + + Object result = interp.eval ("bsf_temp_fn()"); + + if (result != null && result instanceof PyJavaInstance) + result = ((PyJavaInstance)result).__tojava__(Object.class); + return result; + } catch (PyException e) { + throw new BSFException (BSFException.REASON_EXECUTION_ERROR, + "exception from Jython:\n" + e, e); + } + } + + /** + * Evaluate an expression. + */ + public Object eval (String source, int lineNo, int columnNo, + Object script) throws BSFException { + try { + Object result = interp.eval (byteify(script.toString ())); + if (result != null && result instanceof PyJavaInstance) + result = ((PyJavaInstance)result).__tojava__(Object.class); + return result; + } catch (PyException e) { + throw new BSFException (BSFException.REASON_EXECUTION_ERROR, + "exception from Jython:\n" + e, e); + } + } + + /** + * Execute a script. + */ + public void exec (String source, int lineNo, int columnNo, + Object script) throws BSFException { + try { + interp.exec (byteify(script.toString ())); + } catch (PyException e) { + throw new BSFException (BSFException.REASON_EXECUTION_ERROR, + "exception from Jython:\n" + e, e); + } + } + + /** + * Execute script code, emulating console interaction. + */ + public void iexec (String source, int lineNo, int columnNo, + Object script) throws BSFException { + String scriptStr = byteify(script.toString()); + int newline = scriptStr.indexOf("\n"); + + if (newline > -1) + scriptStr = scriptStr.substring(0, newline); + + try { + if (interp.buffer.length() > 0) + interp.buffer.append("\n"); + interp.buffer.append(scriptStr); + if (!(interp.runsource(interp.buffer.toString()))) + interp.resetbuffer(); + } catch (PyException e) { + interp.resetbuffer(); + throw new BSFException(BSFException.REASON_EXECUTION_ERROR, + "exception from Jython:\n" + e, e); + } + } + + /** + * Initialize the engine. + */ + public void initialize (BSFManager mgr, String lang, + Vector declaredBeans) throws BSFException { + super.initialize (mgr, lang, declaredBeans); + + // create an interpreter + interp = new BSFPythonInterpreter (); + + // ensure that output and error streams are re-directed correctly + interp.setOut(System.out); + interp.setErr(System.err); + + // register the mgr with object name "bsf" + interp.set ("bsf", new BSFFunctions (mgr, this)); + + // Declare all declared beans to the interpreter + int size = declaredBeans.size (); + for (int i = 0; i < size; i++) { + declareBean ((BSFDeclaredBean) declaredBeans.elementAt (i)); + } + } + + /** + * Undeclare a previously declared bean. + */ + public void undeclareBean (BSFDeclaredBean bean) throws BSFException { + interp.set (bean.name, null); + } + + public Object unwrap(PyObject result) { + if (result != null) { + Object ret = result.__tojava__(Object.class); + if (ret != Py.NoConversion) + return ret; + } + return result; + } + + private String byteify (String orig) { + // Ugh. Jython likes to be fed bytes, rather than the input string. + ByteArrayInputStream bais = + new ByteArrayInputStream(orig.getBytes()); + StringBuffer s = new StringBuffer(); + int c; + + while ((c = bais.read()) >= 0) { + s.append((char)c); + } + + return s.toString(); + } + + private class BSFPythonInterpreter extends InteractiveInterpreter { + + public BSFPythonInterpreter() { + super(); + } + + // Override runcode so as not to print the stack dump + public void runcode(PyObject code) { + try { + this.exec(code); + } catch (PyException exc) { + throw exc; + } + } + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/netrexx/NetRexxEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/netrexx/NetRexxEngine.java new file mode 100644 index 000000000..40ea27466 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/engines/netrexx/NetRexxEngine.java @@ -0,0 +1,497 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.engines.netrexx; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Hashtable; +import java.util.Vector; + +import com.volmit.iris.util.bsf.BSFDeclaredBean; +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; +import com.volmit.iris.util.bsf.util.BSFEngineImpl; +import com.volmit.iris.util.bsf.util.BSFFunctions; +import com.volmit.iris.util.bsf.util.EngineUtils; +import com.volmit.iris.util.bsf.util.MethodUtils; +import com.volmit.iris.util.bsf.util.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This is the interface to NetRexx from the + * Bean Scripting Framework. + *

+ * The NetRexx code must be written script-style, without a "class" or + * "properties" section preceeding the executable code. The NetRexxEngine will + * generate a prefix for this code: + *

+ * 
+ * class $$CLASSNAME$$;
+ * method BSFNetRexxEngineEntry(bsf=com.volmit.iris.util.bsf.BSFManager) public static;
+ * 
+ * 
+ * $$CLASSNAME$$ will be replaced by a generated classname of the form + * BSFNetRexx*, and the bsf parameter can be used to retrieve application + * objects registered with the Bean Scripting Framework. + *

+ * If you use the placeholder string $$CLASSNAME$$ elsewhere + * in your script -- including within text strings -- BSFNetRexxEngine will + * replace it with the generated name of the class before the NetRexx code + * is compiled. + *

+ * If you need to use full NetRexx functionality, we recommend that your + * NetRexx script define and invoke a "minor class", with or without the + * "dependent" keyword as suits your needs. You'll have to use $$CLASSNAME$$ + * in naming the minor class, since the name of the main class is synthesized; + * for example, to create the minor class "bar" you'd write + * "class $$CLASSNAME$$.Bar". + *

+ *

Hazards:

+ *

+ * Since NetRexx has to be _compiled_ to a Java classfile, invoking it involves + * a fair amount of computation to load and execute the compiler. We are + * currently making an attempt to manage that by caching the class + * after it has been loaded, but the indexing is fairly primitive; we + * hash against the script string to find the class for it. + *

+ * Minor-class .class files are now being deleted after the major class loads. + * This coould potentially cause problems. + * + * @author Joe Kesselman + * @author Sanjiva Weerawarana + */ +public class NetRexxEngine extends BSFEngineImpl +{ + BSFFunctions mgrfuncs; + static Hashtable codeToClass=new Hashtable(); + static String serializeCompilation=""; + static String placeholder="$$CLASSNAME$$"; + String minorPrefix; + + private Log logger = LogFactory.getLog(this.getClass().getName()); + + /** + * Create a scratchfile, open it for writing, return its name. + * Relies on the filesystem to provide us with uniqueness testing. + * NOTE THAT uniqueFileOffset continues to count; we don't want to + * risk reusing a classname we have previously loaded in this session + * even if the classfile has been deleted. + * + * I've made the offset static, due to concerns about reuse/reentrancy + * of the NetRexx engine. + */ + private static int uniqueFileOffset=0; + private class GeneratedFile + { + File file=null; + FileOutputStream fos=null; + String className=null; + GeneratedFile(File file,FileOutputStream fos,String className) + { + this.file=file; + this.fos=fos; + this.className=className; + } + } + + // rexxclass used to be an instance variable, on the theory that + // each NetRexxEngine was an instance of a specific script. + // BSF is currently reusing Engines, so caching the class + // no longer makes sense. + // Class rexxclass; + + /** + * Constructor. + */ + public NetRexxEngine () + { + /* + The following line is intended to cause the constructor to + throw a NoClassDefFoundError if the NetRexxC.zip dependency + is not resolved. + + If this line was not here, the problem would not surface until + the actual processing of a script. We want to know all is well + at the time the engine is instantiated, not when we attempt to + process a script. + */ + + new netrexx.lang.BadArgumentException(); + } + /** + * Return an object from an extension. + * @param object object from which to call our static method + * @param method The name of the method to call. + * @param args an array of arguments to be + * passed to the extension, which may be either + * Vectors of Nodes, or Strings. + */ + public Object call (Object object, String method, Object[] args) + throws BSFException + { + throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE, + "NetRexx doesn't currently support call()", + null); + } + /** + * Invoke a static method. + * @param rexxclass Class to invoke the method against + * @param method The name of the method to call. + * @param args an array of arguments to be + * passed to the extension, which may be either + * Vectors of Nodes, or Strings. + */ + Object callStatic(Class rexxclass, String method, Object[] args) + throws BSFException + { + //***** ISSUE: Currently supports only static methods + Object retval = null; + try + { + if (rexxclass != null) + { + //***** This should call the lookup used in BML, for typesafety + Class[] argtypes=new Class[args.length]; + for(int i=0;i + * Note that NetRexx compilation imposes serious overhead -- 11 seconds for + * the first compile, about 3 thereafter -- but in exchange you get + * Java-like speeds once the classes have been created (minus the cache + * lookup cost). + *

+ * Nobody knows whether javac is threadsafe. + * I'm going to serialize access to the compilers to protect it. + */ + public Object execEvalShared (String source, int lineNo, int columnNo, + Object oscript,boolean returnsObject) + throws BSFException + { + Object retval=null; + String classname=null; + GeneratedFile gf=null; + + // Moved into the exec process; see comment above. + Class rexxclass=null; + + String basescript=oscript.toString(); + String script=basescript; // May be altered by $$CLASSNAME$$ expansion + + try { + // Do we already have a class exactly matching this code? + rexxclass=(Class)codeToClass.get(basescript); + + if(rexxclass!=null) + + { + logger.debug("NetRexxEngine: Found pre-compiled class" + + " for script '" + basescript + "'"); + classname=rexxclass.getName(); + } + else + { + gf=openUniqueFile(tempDir,"BSFNetRexx",".nrx"); + if(gf==null) + throw new BSFException("couldn't create NetRexx scratchfile"); + + // Obtain classname + classname=gf.className; + + // Decide whether to declare a return type + String returnsDecl=""; + if(returnsObject) + returnsDecl="returns java.lang.Object"; + + // Write the kluge header to the file. + // ***** By doing so we give up the ability to use Property blocks. + gf.fos.write(("class "+classname+";\n") + .getBytes()); + gf.fos.write( + ("method BSFNetRexxEngineEntry(bsf=com.volmit.iris.util.bsf.util.BSFFunctions) "+ + " public static "+returnsDecl+";\n") + .getBytes()); + + // Edit the script to replace placeholder with the generated + // classname. Note that this occurs _after_ the cache was + // checked! + int startpoint,endpoint; + if((startpoint=script.indexOf(placeholder))>=0) + { + StringBuffer changed=new StringBuffer(); + for(; + startpoint>=0; + startpoint=script.indexOf(placeholder,startpoint)) + { + changed.setLength(0); // Reset for 2nd pass or later + if(startpoint>0) + changed.append(script.substring(0,startpoint)); + changed.append(classname); + endpoint=startpoint+placeholder.length(); + if(endpoint0;) + { + file=new File(minor_classfiles[--i]); + file.delete(); + } + } + } + + return retval; + } + public void initialize(BSFManager mgr, String lang,Vector declaredBeans) + throws BSFException + { + super.initialize(mgr, lang, declaredBeans); + mgrfuncs = new BSFFunctions (mgr, this); + } +private GeneratedFile openUniqueFile(String directory,String prefix,String suffix) + { + File file=null,obj=null; + FileOutputStream fos=null; + int max=1000; // Don't try forever + GeneratedFile gf=null; + int i; + String className = null; + for(i=max,++uniqueFileOffset; + fos==null && i>0; + --i,++uniqueFileOffset) + { + // Probably a timing hazard here... *************** + try + { + className = prefix+uniqueFileOffset; + file=new File(directory+File.separatorChar+className+suffix); + obj=new File(directory+File.separatorChar+className+".class"); + if(file!=null && !file.exists() & obj!=null & !obj.exists()) + fos=new FileOutputStream(file); + } + catch(Exception e) + { + // File could not be opened for write, or Security Exception + // was thrown. If someone else created the file before we could + // open it, that's probably a threading conflict and we don't + // bother reporting it. + if(!file.exists()) + { + logger.error("openUniqueFile: unexpected "+e); + } + } + } + if(fos==null) + logger.error("openUniqueFile: Failed "+max+"attempts."); + else + gf=new GeneratedFile(file,fos,className); + return gf; + } + + public void undeclareBean (BSFDeclaredBean bean) throws BSFException {} +} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTEngine.java new file mode 100644 index 000000000..893ab62c3 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTEngine.java @@ -0,0 +1,193 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.engines.xslt; + +import java.io.File; +import java.io.Reader; +import java.io.StringReader; +import java.net.URL; +import java.util.Vector; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamSource; + +import com.volmit.iris.util.bsf.BSFDeclaredBean; +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; +import com.volmit.iris.util.bsf.util.BSFEngineImpl; +import com.volmit.iris.util.bsf.util.BSFFunctions; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.xpath.objects.XObject; +import org.w3c.dom.Node; + +/** + * Xerces XSLT interface to BSF. Requires Xalan and Xerces from Apache. + * + * This integration uses the BSF registry to pass in any src document + * and stylesheet base URI that the user may wish to set. + * + * @author Sanjiva Weerawarana + * @author Sam Ruby + * + * Re-implemented for the Xalan 2 codebase + * + * @author Victor J. Orlikowski + */ +public class XSLTEngine extends BSFEngineImpl { + TransformerFactory tFactory; + Transformer transformer; + + Log logger = LogFactory.getLog(this.getClass().getName()); + + /** + * call the named method of the given object. + */ + public Object call (Object object, String method, Object[] args) + throws BSFException { + throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE, + "BSF:XSLTEngine can't call methods"); + } + + /** + * Declare a bean by setting it as a parameter + */ + public void declareBean (BSFDeclaredBean bean) throws BSFException { + transformer.setParameter (bean.name, new XObject (bean.bean)); + } + + /** + * Evaluate an expression. In this case, an expression is assumed + * to be a stylesheet of the template style (see the XSLT spec). + */ + public Object eval (String source, int lineNo, int columnNo, + Object oscript) throws BSFException { + // get the style base URI (the place from where Xerces XSLT will + // look for imported/included files and referenced docs): if a + // bean named "xslt:styleBaseURI" is registered, then cvt it + // to a string and use that. Otherwise use ".", which means the + // base is the directory where the process is running from + Object sbObj = mgr.lookupBean ("xslt:styleBaseURI"); + String styleBaseURI = (sbObj == null) ? "." : sbObj.toString (); + + // Locate the stylesheet. + StreamSource styleSource; + + styleSource = + new StreamSource(new StringReader(oscript.toString ())); + styleSource.setSystemId(styleBaseURI); + + try { + transformer = tFactory.newTransformer(styleSource); + } catch (Exception e) { + logger.error("Exception from Xerces XSLT:", e); + throw new BSFException (BSFException.REASON_EXECUTION_ERROR, + "Exception from Xerces XSLT: " + e, e); + } + + // get the src to work on: if a bean named "xslt:src" is registered + // and its a Node, then use it as the source. If its not a Node, then + // if its a URL parse it, if not treat it as a file and make a URL and + // parse it and go. If no xslt:src is found, use an empty document + // (stylesheet is treated as a literal result element stylesheet) + Object srcObj = mgr.lookupBean ("xslt:src"); + Object xis = null; + if (srcObj != null) { + if (srcObj instanceof Node) { + xis = new DOMSource((Node)srcObj); + } else { + try { + String mesg = "as anything"; + if (srcObj instanceof Reader) { + xis = new StreamSource ((Reader) srcObj); + mesg = "as a Reader"; + } else if (srcObj instanceof File) { + xis = new StreamSource ((File) srcObj); + mesg = "as a file"; + } else { + String srcObjstr=srcObj.toString(); + xis = new StreamSource (new StringReader(srcObjstr)); + if (srcObj instanceof URL) { + mesg = "as a URL"; + } else { + ((StreamSource) xis).setPublicId (srcObjstr); + mesg = "as an XML string"; + } + } + + if (xis == null) { + throw new Exception ("Unable to get input from '" + + srcObj + "' " + mesg); + } + } catch (Exception e) { + throw new BSFException (BSFException.REASON_EXECUTION_ERROR, + "BSF:XSLTEngine: unable to get " + + "input from '" + srcObj + "' as XML", e); + } + } + } else { + // create an empty document - real src must come into the + // stylesheet using "doc(...)" [see XSLT spec] or the stylesheet + // must be of literal result element type + xis = new StreamSource(); + } + + // set all declared beans as parameters. + for (int i = 0; i < declaredBeans.size (); i++) { + BSFDeclaredBean b = (BSFDeclaredBean) declaredBeans.elementAt (i); + transformer.setParameter (b.name, new XObject (b.bean)); + } + + // declare a "bsf" parameter which is the BSF handle so that + // the script can do BSF stuff if it wants to + transformer.setParameter ("bsf", + new XObject (new BSFFunctions (mgr, this))); + + // do it + try { + DOMResult result = new DOMResult(); + transformer.transform ((StreamSource) xis, result); + return new XSLTResultNode (result.getNode()); + } catch (Exception e) { + throw new BSFException (BSFException.REASON_EXECUTION_ERROR, + "exception while eval'ing XSLT script" + e, e); + } + } + + /** + * Initialize the engine. + */ + public void initialize (BSFManager mgr, String lang, + Vector declaredBeans) throws BSFException { + super.initialize (mgr, lang, declaredBeans); + + tFactory = TransformerFactory.newInstance(); + } + + /** + * Undeclare a bean by setting he parameter represeting it to null + */ + public void undeclareBean (BSFDeclaredBean bean) throws BSFException { + // Cannot clear only one parameter in Xalan 2, so we set it to null + if ((transformer.getParameter (bean.name)) != null) { + transformer.setParameter (bean.name, null); + } + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTResultNode.java b/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTResultNode.java new file mode 100644 index 000000000..612ded3f7 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTResultNode.java @@ -0,0 +1,33 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.engines.xslt; + +import org.w3c.dom.Node; + +public class XSLTResultNode +{ + Node node; + + public XSLTResultNode(Node node) + { + this.node = node; + } + public Node getNode() + { + return node; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/BSFClassLoader.java b/src/main/java/com/volmit/iris/util/bsf/util/BSFClassLoader.java new file mode 100644 index 000000000..557838e8d --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/BSFClassLoader.java @@ -0,0 +1,74 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.io.File; +import java.io.FileInputStream; +import java.util.Hashtable; + +/** + * This class loader knows to load a class from the tempDir dir + * of the environment of the given manager. + * + * @author Sanjiva Weerawarana + */ +class BSFClassLoader extends ClassLoader { + Hashtable cache = new Hashtable (); + String tempDir = "."; + + // note the non-public constructor - this is only avail within + // this package. + BSFClassLoader () { + } + public synchronized Class loadClass (String name, boolean resolve) + throws ClassNotFoundException { + Class c = (Class) cache.get (name); + if (c == null) { + // is it a system class + try { + c = findSystemClass (name); + cache.put (name, c); + return c; + } catch (ClassNotFoundException e) { + // nope + } + try { + byte[] data = loadClassData (name); + c = defineClass (name, data, 0, data.length); + cache.put (name, c); + } catch (Exception e) { + e.printStackTrace (); + throw new ClassNotFoundException ("unable to resolve class '" + + name + "'"); + } + } + if (resolve) + resolveClass (c); + return c; + } + private byte[] loadClassData (String name) throws Exception { + String fileName = tempDir + File.separatorChar + name + ".class"; + FileInputStream fi = new FileInputStream (fileName); + byte[] data = new byte[fi.available ()]; + fi.read (data); + fi.close(); + return data; + } + public void setTempDir (String tempDir) { + this.tempDir = tempDir; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/BSFEngineImpl.java b/src/main/java/com/volmit/iris/util/bsf/util/BSFEngineImpl.java new file mode 100644 index 000000000..d38dead04 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/BSFEngineImpl.java @@ -0,0 +1,203 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.beans.PropertyChangeEvent; +import java.util.Vector; + +import com.volmit.iris.util.bsf.BSFDeclaredBean; +import com.volmit.iris.util.bsf.BSFEngine; +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; + +/** + * This is a base implementation of the BSFEngine interface which + * engine implementations may choose to extend to get the basic + * methods of the interface implemented. + *

+ * + * @author Sanjiva Weerawarana + * @author Olivier Gruber (added original debugging support) + */ + +public abstract class BSFEngineImpl implements BSFEngine { + + protected BSFManager mgr; // my manager + protected String lang; // my language string + protected Vector declaredBeans; // BSFDeclaredBeans + protected String classPath; + protected String tempDir; + protected ClassLoader classLoader; + + /** + * Default impl of apply - calls eval ignoring parameters and returns + * the result. + */ + public Object apply(String source, int lineNo, int columnNo, + Object funcBody, Vector paramNames, Vector arguments) + throws BSFException { + return eval(source, lineNo, columnNo, funcBody); + } + + /** + * Default impl of compileApply - calls compileExpr ignoring parameters. + */ + public void compileApply(String source, int lineNo, int columnNo, + Object funcBody, Vector paramNames, + Vector arguments, CodeBuffer cb) + throws BSFException { + compileExpr(source, lineNo, columnNo, funcBody, cb); + } + + /** + * Default impl of compileExpr - generates code that'll create a new + * manager, evaluate the expression, and return the value. + */ + public void compileExpr(String source, int lineNo, int columnNo, + Object expr, CodeBuffer cb) throws BSFException { + ObjInfo bsfInfo = cb.getSymbol("bsf"); + + if (bsfInfo == null) { + bsfInfo = new ObjInfo(BSFManager.class, "bsf"); + cb.addFieldDeclaration("com.volmit.iris.util.bsf.BSFManager bsf = " + + "new com.volmit.iris.util.bsf.BSFManager();"); + cb.putSymbol("bsf", bsfInfo); + } + + String evalString = bsfInfo.objName + ".eval(\"" + lang + "\", "; + evalString += "request.getRequestURI(), " + lineNo + ", " + columnNo; + evalString += "," + StringUtils.lineSeparator; + evalString += StringUtils.getSafeString(expr.toString()) + ")"; + + ObjInfo oldRet = cb.getFinalServiceMethodStatement(); + + if (oldRet != null && oldRet.isExecutable()) { + cb.addServiceMethodStatement(oldRet.objName + ";"); + } + + cb.setFinalServiceMethodStatement(new ObjInfo(Object.class, + evalString)); + + cb.addServiceMethodException("com.volmit.iris.util.bsf.BSFException"); + } + + /** + * Default impl of compileScript - generates code that'll create a new + * manager, and execute the script. + */ + public void compileScript(String source, int lineNo, int columnNo, + Object script, CodeBuffer cb) + throws BSFException { + ObjInfo bsfInfo = cb.getSymbol("bsf"); + + if (bsfInfo == null) { + bsfInfo = new ObjInfo(BSFManager.class, "bsf"); + cb.addFieldDeclaration("com.volmit.iris.util.bsf.BSFManager bsf = " + + "new com.volmit.iris.util.bsf.BSFManager();"); + cb.putSymbol("bsf", bsfInfo); + } + + String execString = bsfInfo.objName + ".exec(\"" + lang + "\", "; + execString += "request.getRequestURI(), " + lineNo + ", " + columnNo; + execString += "," + StringUtils.lineSeparator; + execString += StringUtils.getSafeString(script.toString()) + ")"; + + ObjInfo oldRet = cb.getFinalServiceMethodStatement(); + + if (oldRet != null && oldRet.isExecutable()) { + cb.addServiceMethodStatement(oldRet.objName + ";"); + } + + cb.setFinalServiceMethodStatement(new ObjInfo(void.class, execString)); + + cb.addServiceMethodException("com.volmit.iris.util.bsf.BSFException"); + } + + public void declareBean(BSFDeclaredBean bean) throws BSFException { + throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE, + "language " + lang + + " does not support declareBean(...)."); + } + + /** + * Default impl of execute - calls eval and ignores the result. + */ + public void exec(String source, int lineNo, int columnNo, Object script) + throws BSFException { + eval(source, lineNo, columnNo, script); + } + + /** + * Default impl of interactive execution - calls eval and ignores the result. + */ + public void iexec(String source, int lineNo, int columnNo, Object script) + throws BSFException { + eval(source, lineNo, columnNo, script); + } + + /** + * initialize the engine; called right after construction by + * the manager. Declared beans are simply kept in a vector and + * that's it. Subclasses must do whatever they want with it. + */ + public void initialize(BSFManager mgr, String lang, Vector declaredBeans) + throws BSFException { + + this.mgr = mgr; + this.lang = lang; + this.declaredBeans = declaredBeans; + + // initialize my properties from those of the manager. It'll send + // propagate change events to me + this.classPath = mgr.getClassPath(); + this.tempDir = mgr.getTempDir(); + this.classLoader = mgr.getClassLoader(); + } + + /** + * Receive property change events from the manager and update my fields + * as needed. + * + * @param e PropertyChange event with the change data + */ + public void propertyChange(PropertyChangeEvent e) { + String name = e.getPropertyName(); + Object value = e.getNewValue(); + + if (name.equals("classPath")) { + classPath = (String) value; + } + else if (name.equals("tempDir")) { + tempDir = (String) value; + } + else if (name.equals("classLoader")) { + classLoader = (ClassLoader) value; + } + } + + public void terminate() { + mgr = null; + declaredBeans = null; + classLoader = null; + } + + public void undeclareBean(BSFDeclaredBean bean) throws BSFException { + throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE, + "language " + lang + + " does not support undeclareBean(...)."); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessor.java b/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessor.java new file mode 100644 index 000000000..b59baca29 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessor.java @@ -0,0 +1,92 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import com.volmit.iris.util.bsf.BSFEngine; +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; +import com.volmit.iris.util.bsf.util.event.EventProcessor; + +/** + * This is used to support binding scripts to be run when an event + * occurs. + * + * @author Sanjiva Weerawarana + */ +public class BSFEventProcessor implements EventProcessor { + BSFEngine engine; + BSFManager manager; + String filter; + String source; + int lineNo; + int columnNo; + Object script; + + /** + * Package-protected constructor makes this class unavailable for + * public use. + */ + BSFEventProcessor (BSFEngine engine, BSFManager manager, String filter, + String source, int lineNo, int columnNo, Object script) + throws BSFException { + this.engine = engine; + this.manager = manager; + this.filter = filter; + this.source = source; + this.lineNo = lineNo; + this.columnNo = columnNo; + this.script = script; + } + ////////////////////////////////////////////////////////////////////////// + // + // event is delegated to me by the adapters using this. inFilter is + // in general the name of the method via which the event was received + // at the adapter. For prop/veto change events, inFilter is the name + // of the property. In any case, in the event processor, I only forward + // those events if for which the filters match (if one is specified). + + public void processEvent (String inFilter, Object[] evtInfo) { + try { + processExceptionableEvent (inFilter, evtInfo); + } catch (RuntimeException re) { + // rethrow this .. I don't want to intercept run-time stuff + // that can in fact occur legit + throw re; + } catch (Exception e) { + // should not occur + System.err.println ("BSFError: non-exceptionable event delivery " + + "threw exception (that's not nice): " + e); + e.printStackTrace (); + } + } + ////////////////////////////////////////////////////////////////////////// + // + // same as above, but used when the method event method may generate + // an exception which must go all the way back to the source (as in + // the vetoableChange case) + + public void processExceptionableEvent (String inFilter, Object[] evtInfo) throws Exception + { + if ((filter != null) && !filter.equals (inFilter)) { + // ignore this event + return; + } + + // run the script + engine.exec (source, lineNo, columnNo, script); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessorReturningEventInfos.java b/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessorReturningEventInfos.java new file mode 100644 index 000000000..a8aac16b1 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessorReturningEventInfos.java @@ -0,0 +1,164 @@ +/* + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * Sanjiva Weerawarana and others at International Business Machines + * Corporation. For more information on the Apache Software Foundation, + * please see . + */ + +package com.volmit.iris.util.bsf.util; + +import java.util.Vector; + +import com.volmit.iris.util.bsf.BSFEngine; +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; +import com.volmit.iris.util.bsf.util.event.EventProcessor; + +/* + * Copyright (C) 2001-2006 Rony G. Flatscher + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + */ + +/** + * + * This is used to support binding scripts to be run when an event occurs, + * forwarding the arguments supplied to the event listener. It is an adapted + * version of com.volmit.iris.util.bsf.util.BSFEventProcessor. + * + * @author Rony G. Flatscher, but most of the code copied from + * com.volmit.iris.util.bsf.util.BSFEventProcessor by Sanjiva Weerawarana + */ +public class BSFEventProcessorReturningEventInfos implements EventProcessor { + BSFEngine engine; + + BSFManager manager; + + String filter; + + String source; + + int lineNo; + + int columnNo; + + Object script; + + Object dataFromScriptingEngine; // ---rgf, 2006-02-24: data coming from the + // script engine, could be + + // e.g. an object reference to forward event with received arguments to + + /** + * Package-protected constructor makes this class unavailable for public + * use. + * + * @param dataFromScriptingEngine + * this contains any object supplied by the scripting engine and + * gets sent back with the supplied script. This could be used + * e.g. for indicating which scripting engine object should be + * ultimately informed of the event occurrence. + */ + BSFEventProcessorReturningEventInfos(BSFEngine engine, BSFManager manager, + String filter, String source, int lineNo, int columnNo, + Object script, Object dataFromScriptingEngine) throws BSFException { + this.engine = engine; + this.manager = manager; + this.filter = filter; + this.source = source; + this.lineNo = lineNo; + this.columnNo = columnNo; + this.script = script; + this.dataFromScriptingEngine = dataFromScriptingEngine; + } + + // //////////////////////////////////////////////////////////////////////// + // + // event is delegated to me by the adapters using this. inFilter is + // in general the name of the method via which the event was received + // at the adapter. For prop/veto change events, inFilter is the name + // of the property. In any case, in the event processor, I only forward + // those events if for which the filters match (if one is specified). + + public void processEvent(String inFilter, Object[] evtInfo) { + try { + processExceptionableEvent(inFilter, evtInfo); + } catch (RuntimeException re) { + // rethrow this .. I don't want to intercept run-time stuff + // that can in fact occur legit + throw re; + } catch (Exception e) { + // should not occur + System.err.println("BSFError: non-exceptionable event delivery " + + "threw exception (that's not nice): " + e); + e.printStackTrace(); + } + } + + // //////////////////////////////////////////////////////////////////////// + // + // same as above, but used when the method event method may generate + // an exception which must go all the way back to the source (as in + // the vetoableChange case) + + public void processExceptionableEvent(String inFilter, Object[] evtInfo) + throws Exception { + + // System.err.println(this+": inFilter=["+inFilter+"], + // filter=["+filter+"]"); + if ((filter != null) && !filter.equals(inFilter)) { + // ignore this event + return; + } + + // run the script + // engine.exec (source, lineNo, columnNo, script); + + // create the parameter vectors for engine.apply() + Vector paramNames = new Vector(), paramValues = new Vector(); + + // parameter # 1 + // supply the parameters as an array object as sent to the event object + // listener + // (usually the first entry is the sent event object) + paramNames.add("eventParameters"); + paramValues.add(evtInfo); + + // parameter # 2 + // supply the data object received from the scripting engine to be sent + // with the event + paramNames.add("dataFromScriptingEngine"); + paramValues.add(this.dataFromScriptingEngine); // can be null as well + + // parameter # 3 + // event filter in place + paramNames.add("inFilter"); + paramValues.add(inFilter); // event name that has occurred + + // parameter # 4 + // event filter in place + paramNames.add("eventFilter"); + paramValues.add(this.filter); // can be null as well + + // parameter # 5 + // BSF manager instance (e.g. allows access to its registry) + paramNames.add("BSFManager"); + paramValues.add(this.manager); + + engine.apply(source, lineNo, columnNo, this.script, paramNames, + paramValues); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/BSFFunctions.java b/src/main/java/com/volmit/iris/util/bsf/util/BSFFunctions.java new file mode 100644 index 000000000..08ded56ec --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/BSFFunctions.java @@ -0,0 +1,54 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import com.volmit.iris.util.bsf.BSFEngine; +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; + +/** + * This is a utility that engine implementors may use as the Java + * object they expose in the scripting language as "bsf". This has + * essentially a subset of the methods in BSFManager plus some + * stuff from the utils. Currently used by Javascript (Rhino) & BML. + * + * @author Sanjiva Weerawarana + */ +public class BSFFunctions { + BSFManager mgr; + BSFEngine engine; + + public BSFFunctions (BSFManager mgr, BSFEngine engine) { + this.mgr = mgr; + this.engine = engine; + } + public void addEventListener (Object src, String eventSetName, + String filter, Object script) + throws BSFException { + EngineUtils.addEventListener (src, eventSetName, filter, engine, + mgr, "", 0, 0, script); + } + public Object lookupBean (String name) { + return mgr.lookupBean (name); + } + public void registerBean (String name, Object bean) { + mgr.registerBean (name, bean); + } + public void unregisterBean (String name) { + mgr.unregisterBean (name); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/Bean.java b/src/main/java/com/volmit/iris/util/bsf/util/Bean.java new file mode 100644 index 000000000..d6fdd752f --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/Bean.java @@ -0,0 +1,38 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +/** + * A Bean is the class used to represent a bean: it holds a + * type and a value. This is needed because otherwise we can't represent + * the types of null-valued beans (or primitives) correctly. This was + * originally in the BML player. + * + * @author Sanjiva Weerawarana + */ +public class Bean { + // type of this bean + public Class type; + + // its current value (mebbe null) + public Object value; + + public Bean (Class type, Object value) { + this.type = type; + this.value = value; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/CodeBuffer.java b/src/main/java/com/volmit/iris/util/bsf/util/CodeBuffer.java new file mode 100644 index 000000000..e38a12582 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/CodeBuffer.java @@ -0,0 +1,479 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.io.PrintWriter; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Hashtable; +import java.util.Stack; +import java.util.Vector; + +import com.volmit.iris.util.bsf.util.cf.CodeFormatter; + +/** + * A CodeBuffer object is used as a code repository for generated Java code. + * It provides buffers which correspond to the various sections of a Java class. + * + * @author Matthew J. Duftler + */ +public class CodeBuffer +{ + private StringWriter fieldDeclSW = new StringWriter(), + methodDeclSW = new StringWriter(), + initializerSW = new StringWriter(), + constructorSW = new StringWriter(), + serviceMethodSW = new StringWriter(); + + private PrintWriter fieldDeclPW = new PrintWriter(fieldDeclSW), + methodDeclPW = new PrintWriter(methodDeclSW), + initializerPW = new PrintWriter(initializerSW), + constructorPW = new PrintWriter(constructorSW), + serviceMethodPW = new PrintWriter(serviceMethodSW); + + private Stack symbolTableStack = new Stack(); + private Hashtable symbolTable = new Hashtable(), + usedSymbolIndices = new Hashtable(); + + private ObjInfo finalStatementInfo; + private CodeBuffer parent; + + + { + symbolTableStack.push(symbolTable); + } + + // New stuff... + private Vector imports = new Vector(), + constructorArguments = new Vector(), + constructorExceptions = new Vector(), + serviceMethodExceptions = new Vector(), + implementsVector = new Vector(); + private String packageName = null, + className = "Test", + serviceMethodName = "exec", + extendsName = null; + private Class serviceMethodReturnType = void.class; + + public CodeBuffer() + { + } + public CodeBuffer(CodeBuffer parent) + { + this.parent = parent; + } + public void addConstructorArgument(ObjInfo arg) + { + constructorArguments.addElement(arg); + } + public void addConstructorException(String exceptionName) + { + if (!constructorExceptions.contains(exceptionName)) + { + constructorExceptions.addElement(exceptionName); + } + } + public void addConstructorStatement(String statement) + { + constructorPW.println(statement); + } + public void addFieldDeclaration(String statement) + { + fieldDeclPW.println(statement); + } + public void addImplements(String importName) + { + if (!implementsVector.contains(importName)) + { + implementsVector.addElement(importName); + } + } + public void addImport(String importName) + { + if (!imports.contains(importName)) + { + imports.addElement(importName); + } + } + public void addInitializerStatement(String statement) + { + initializerPW.println(statement); + } + public void addMethodDeclaration(String statement) + { + methodDeclPW.println(statement); + } + public void addServiceMethodException(String exceptionName) + { + if (!serviceMethodExceptions.contains(exceptionName)) + { + serviceMethodExceptions.addElement(exceptionName); + } + } + public void addServiceMethodStatement(String statement) + { + serviceMethodPW.println(statement); + } + // Used internally by merge(...). + private void appendIfNecessary(PrintWriter pw, StringBuffer buf) + { + if (buf.length() > 0) + { + pw.print(buf.toString()); + } + } + public String buildNewSymbol(String prefix) + { + Integer nextNum = getSymbolIndex(prefix); + + if (nextNum == null) + { + nextNum = new Integer(0); + } + + int iNextNum = nextNum.intValue(); + String symbol = prefix + "_" + iNextNum; + + while (getSymbol(symbol) != null) + { + iNextNum++; + symbol = prefix + "_" + iNextNum; + } + + putSymbolIndex(prefix, new Integer(iNextNum + 1)); + + return symbol; + } + public void clearSymbolTable() + { + symbolTable = new Hashtable(); + symbolTableStack = new Stack(); + symbolTableStack.push(symbolTable); + + usedSymbolIndices = new Hashtable(); + } + public String getClassName() + { + return className; + } + public Vector getConstructorArguments() + { + return constructorArguments; + } + public StringBuffer getConstructorBuffer() + { + constructorPW.flush(); + + return constructorSW.getBuffer(); + } + public Vector getConstructorExceptions() + { + return constructorExceptions; + } + public String getExtends() + { + return extendsName; + } + public StringBuffer getFieldBuffer() + { + fieldDeclPW.flush(); + + return fieldDeclSW.getBuffer(); + } + public ObjInfo getFinalServiceMethodStatement() + { + return finalStatementInfo; + } + public Vector getImplements() + { + return implementsVector; + } + public Vector getImports() + { + return imports; + } + public StringBuffer getInitializerBuffer() + { + initializerPW.flush(); + + return initializerSW.getBuffer(); + } + public StringBuffer getMethodBuffer() + { + methodDeclPW.flush(); + + return methodDeclSW.getBuffer(); + } + public String getPackageName() + { + return packageName; + } + public StringBuffer getServiceMethodBuffer() + { + serviceMethodPW.flush(); + + return serviceMethodSW.getBuffer(); + } + public Vector getServiceMethodExceptions() + { + return serviceMethodExceptions; + } + public String getServiceMethodName() + { + return serviceMethodName; + } + public Class getServiceMethodReturnType() + { + if (finalStatementInfo != null) + { + return finalStatementInfo.objClass; + } + else if (serviceMethodReturnType != null) + { + return serviceMethodReturnType; + } + else + { + return void.class; + } + } + public ObjInfo getSymbol(String symbol) + { + ObjInfo ret = (ObjInfo)symbolTable.get(symbol); + + if (ret == null && parent != null) + ret = parent.getSymbol(symbol); + + return ret; + } + Integer getSymbolIndex(String prefix) + { + if (parent != null) + { + return parent.getSymbolIndex(prefix); + } + else + { + return (Integer)usedSymbolIndices.get(prefix); + } + } + public Hashtable getSymbolTable() + { + return symbolTable; + } + public void merge(CodeBuffer otherCB) + { + Vector otherImports = otherCB.getImports(); + + for (int i = 0; i < otherImports.size(); i++) + { + addImport((String)otherImports.elementAt(i)); + } + + appendIfNecessary(fieldDeclPW, otherCB.getFieldBuffer()); + appendIfNecessary(methodDeclPW, otherCB.getMethodBuffer()); + appendIfNecessary(initializerPW, otherCB.getInitializerBuffer()); + appendIfNecessary(constructorPW, otherCB.getConstructorBuffer()); + appendIfNecessary(serviceMethodPW, otherCB.getServiceMethodBuffer()); + + ObjInfo oldRet = getFinalServiceMethodStatement(); + + if (oldRet != null && oldRet.isExecutable()) + { + addServiceMethodStatement(oldRet.objName + ";"); + } + + setFinalServiceMethodStatement(otherCB.getFinalServiceMethodStatement()); + } + public void popSymbolTable() + { + symbolTableStack.pop(); + symbolTable = (Hashtable)symbolTableStack.peek(); + } + public void print(PrintWriter out, boolean formatOutput) + { + if (formatOutput) + { + new CodeFormatter().formatCode(new StringReader(toString()), out); + } + else + { + out.print(toString()); + } + + out.flush(); + } + public void pushSymbolTable() + { + symbolTable = (Hashtable)symbolTableStack.push(new ScriptSymbolTable(symbolTable)); + } + public void putSymbol(String symbol, ObjInfo obj) + { + symbolTable.put(symbol, obj); + } + void putSymbolIndex(String prefix, Integer index) + { + if (parent != null) + { + parent.putSymbolIndex(prefix, index); + } + else + { + usedSymbolIndices.put(prefix, index); + } + } + public void setClassName(String className) + { + this.className = className; + } + public void setExtends(String extendsName) + { + this.extendsName = extendsName; + } + public void setFinalServiceMethodStatement(ObjInfo finalStatementInfo) + { + this.finalStatementInfo = finalStatementInfo; + } + public void setPackageName(String packageName) + { + this.packageName = packageName; + } + public void setServiceMethodName(String serviceMethodName) + { + this.serviceMethodName = serviceMethodName; + } + public void setServiceMethodReturnType(Class serviceMethodReturnType) + { + this.serviceMethodReturnType = serviceMethodReturnType; + } + public void setSymbolTable(Hashtable symbolTable) + { + this.symbolTable = symbolTable; + } + public boolean symbolTableIsStacked() + { + return (symbolTable instanceof ScriptSymbolTable); + } + public String toString() + { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + ObjInfo ret = finalStatementInfo; + + if (packageName != null && !packageName.equals("")) + { + pw.println("package " + packageName + ";"); + pw.println(); + } + + if (imports.size() > 0) + { + for (int i = 0; i < imports.size(); i++) + { + pw.println("import " + imports.elementAt(i) + ";"); + } + + pw.println(); + } + + pw.println("public class " + className + + (extendsName != null && !extendsName.equals("") + ? " extends " + extendsName + : "") + + (implementsVector.size() > 0 + ? " implements " + + StringUtils.getCommaListFromVector(implementsVector) + : "") + ); + pw.println("{"); + + pw.print(getFieldBuffer().toString()); + + StringBuffer buf = getInitializerBuffer(); + + if (buf.length() > 0) + { + pw.println(); + pw.println("{"); + pw.print(buf.toString()); + pw.println("}"); + } + + buf = getConstructorBuffer(); + + if (buf.length() > 0) + { + pw.println(); + pw.println("public " + className + "(" + + (constructorArguments.size() > 0 + ? StringUtils.getCommaListFromVector(constructorArguments) + : "" + ) + ")" + + (constructorExceptions.size() > 0 + ? " throws " + + StringUtils.getCommaListFromVector(constructorExceptions) + : "" + ) + ); + pw.println("{"); + pw.print(buf.toString()); + pw.println("}"); + } + + buf = getServiceMethodBuffer(); + + if (buf.length() > 0 || ret != null) + { + pw.println(); + pw.println("public " + + StringUtils.getClassName(getServiceMethodReturnType()) + " " + + serviceMethodName + "()" + + (serviceMethodExceptions.size() > 0 + ? " throws " + + StringUtils.getCommaListFromVector(serviceMethodExceptions) + : "" + ) + ); + pw.println("{"); + + pw.print(buf.toString()); + + if (ret != null) + { + if (ret.isValueReturning()) + { + pw.println(); + pw.println("return " + ret.objName + ";"); + } + else if (ret.isExecutable()) + { + pw.println(ret.objName + ";"); + } + } + + pw.println("}"); + } + + pw.print(getMethodBuffer().toString()); + + pw.println("}"); + + pw.flush(); + + return sw.toString(); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/EngineUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/EngineUtils.java new file mode 100644 index 000000000..90e32f73f --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/EngineUtils.java @@ -0,0 +1,379 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import com.volmit.iris.util.bsf.BSFEngine; +import com.volmit.iris.util.bsf.BSFException; +import com.volmit.iris.util.bsf.BSFManager; + +/** + * This class contains utilities that language integrators can use + * when implementing the BSFEngine interface. + * + * @author Sanjiva Weerawarana + * @author Sam Ruby + * @author Rony G. Flatscher (added addEventListenerReturningEventInfos) + */ +public class EngineUtils { + // the BSF class loader that knows how to load from the a specific + // temp directory + static BSFClassLoader bsfCL; + + // ---rgf, 2003-02-13, determine whether changing accessibility of Methods is possible + static boolean bMethodHasSetAccessible=false; + static { + Class mc=Method.class; // get the "Method" class object + Class arg[]={boolean.class}; // define an array with the primitive "boolean" pseudo class object + try { + mc.getMethod("setAccessible", arg ); // is this method available? + bMethodHasSetAccessible=true; // no exception, hence method exists + } + catch (Exception e) + { + bMethodHasSetAccessible=false;// exception occurred, hence method does not exist + } + } + + + /** + * Add a script as a listener to some event coming out of an object. The + * first two args identify the src of the event and the event set + * and the rest identify the script which should be run when the event + * fires. + * + * @param bean event source + * @param eventSetName name of event set from event src to bind to + * @param filter filter for events + * @param engine BSFEngine which can run this script + * @param manager BSFManager of the above engine + * @param source (context info) the source of this expression + * (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param script the script to execute when the event occurs + * + * @exception BSFException if anything goes wrong while running the script + */ + public static void addEventListener (Object bean, String eventSetName, + String filter, BSFEngine engine, + BSFManager manager, String source, + int lineNo, int columnNo, + Object script) throws BSFException { + BSFEventProcessor ep = new BSFEventProcessor (engine, manager, filter, + source, lineNo, columnNo, + script); + + try { + ReflectionUtils.addEventListener (bean, eventSetName, ep); + } catch (Exception e) { + e.printStackTrace (); + throw new BSFException (BSFException.REASON_OTHER_ERROR, + "ouch while adding event listener: " + + e, e); + } + } + + + /** + * Add a script as a listener to some event coming out of an object. The + * first two args identify the src of the event and the event set + * and the rest identify the script which should be run when the event + * fires. The processing will use the engine's apply() method. + * + * @param bean event source + * @param eventSetName name of event set from event src to bind to + * @param filter filter for events + * @param engine BSFEngine which can run this script + * @param manager BSFManager of the above engine + * @param source (context info) the source of this expression (e.g., filename) + * @param lineNo (context info) the line number in source for expr + * @param columnNo (context info) the column number in source for expr + * @param script the script to execute when the event occurs + * @param dataFromScriptingEngine + * this contains any object supplied by the scripting engine and gets sent + * back with the supplied script, if the event occurs. + * This could be used e.g. for indicating to the scripting engine which + * scripting engine object/routine/function/procedure + * should be ultimately informed of the event occurrence. + * + * @exception BSFException if anything goes wrong while running the script + */ + public static void addEventListenerReturningEventInfos ( Object bean, + String eventSetName, + String filter, + BSFEngine engine, + BSFManager manager, + String source, + int lineNo, + int columnNo, + Object script, + Object dataFromScriptingEngine + ) throws BSFException + { + BSFEventProcessorReturningEventInfos ep = + new BSFEventProcessorReturningEventInfos (engine, + manager, + filter, + source, + lineNo, + columnNo, + script, + dataFromScriptingEngine + ); + + try { + ReflectionUtils.addEventListener (bean, eventSetName, ep); + } catch (Exception e) { + e.printStackTrace (); + throw new BSFException (BSFException.REASON_OTHER_ERROR, + "ouch while adding event listener: " + + e, e); + } + } + + /** + * Finds and invokes a method with the given signature on the given + * bean. The signature of the method that's invoked is first taken + * as the types of the args, but if that fails, this tries to convert + * any primitive wrapper type args to their primitive counterparts + * to see whether a method exists that way. If it does, done. + * + * @param bean the object on which to invoke the method + * @param methodName name of the method + * @param args arguments to be given to the method + * + * @return the result of invoking the method, if any + * + * @exception BSFException if something goes wrong + */ + public static Object callBeanMethod (Object bean, String methodName, + Object[] args) throws BSFException { + Class[] argTypes = null; + // determine arg types. note that a null argtype + // matches any object type + + if (args != null) { + argTypes = new Class[args.length]; + for (int i = 0; i < args.length; i++) { + argTypes[i] = (args[i] == null) ? null : args[i].getClass (); + } + } + + // we want to allow a static call to occur on an object, similar + // to what Java allows. So isStaticOnly is set to false. + boolean isStaticOnly = false; + Class beanClass = (bean instanceof Class) ? (Class)bean : + bean.getClass (); + + // now try to call method with the right signature + try { + Method m; + try { + m = MethodUtils.getMethod (beanClass, methodName, argTypes, + isStaticOnly); + } catch (NoSuchMethodException e) { + // ok, so that didn't work - now try converting any primitive + // wrapper types to their primitive counterparts + try { + // if args is null the NullPointerException will get caught + // below and the right thing'll happen .. ugly but works + for (int i = 0; i < args.length; i++) { + if (args[i] instanceof Number) + { + if (args[i] instanceof Byte) argTypes[i] = byte.class; + else if (args[i] instanceof Integer) argTypes[i] = int.class; + else if (args[i] instanceof Long) argTypes[i] = long.class; + else if (args[i] instanceof Float) argTypes[i] = float.class; + else if (args[i] instanceof Double ) argTypes[i] = double.class; + else if (args[i] instanceof Short ) argTypes[i] = short.class; + } + else if (args[i] instanceof Boolean) argTypes[i] = boolean.class; + else if (args[i] instanceof Character) argTypes[i] = char.class; + } + + m = MethodUtils.getMethod (beanClass, methodName, argTypes, + isStaticOnly); + } catch (Exception e2) { + // throw the original + throw e; + } + } + + // call it, and return the result + try { + return m.invoke (bean, args); + } + catch (Exception e) // 2003-02-23, --rgf, maybe an IllegalAccessException? + { + if (e instanceof IllegalAccessException && + bMethodHasSetAccessible && + Modifier.isPublic(m.getModifiers()) ) // if a public method allow access to it + { + m.setAccessible(true); // allow unconditional access to method + return m.invoke (bean, args); + } + // re-throw the exception + throw e; + } + + } catch (Exception e) { + // something went wrong while invoking method + Throwable t = (e instanceof InvocationTargetException) ? + ((InvocationTargetException)e).getTargetException () : + null; + throw new BSFException (BSFException.REASON_OTHER_ERROR, + "method invocation failed: " + e + + ((t==null) ? "" : + (" target exception: " + t)), t); + } + } + + /** + * Creates a new bean. The signature of the constructor that's invoked + * is first taken as the types of the args, but if that fails, this tries + * to convert any primitive wrapper type args to their primitive + * counterparts to see whether a method exists that way. If it does, done. + * + * @param className fully qualified name of class to instantiate + * @param args array of constructor args (or null if none) + * + * @return the created bean + * + * @exception BSFException if something goes wrong (@see + * org.apache.cs.util.MethodUtils for the real + * exceptions that can occur). + */ + public static Object createBean (String className, Object args[]) + throws BSFException { + Bean obj; + Class[] argTypes = null; + + if (args != null) { + argTypes = new Class[args.length]; + for (int i = 0; i < args.length; i++) { + argTypes[i] = (args[i] != null) ? args[i].getClass () : null; + } + } + + try { + try { + obj = ReflectionUtils.createBean (null, className, + argTypes, args); + return obj.value; + } catch (NoSuchMethodException me) { + // ok, so that didn't work - now try converting any primitive + // wrapper types to their primitive counterparts + try { + // if args is null the NullPointerException will get caught + // below and the right thing'll happen .. ugly but works + for (int i = 0; i < args.length; i++) { + if (args[i] instanceof Number) + argTypes[i] = byte.class; + else if (args[i] instanceof Boolean) + argTypes[i] = boolean.class; + else if (args[i] instanceof Character) + argTypes[i] = char.class; + } + obj = ReflectionUtils.createBean (null, className, + argTypes, args); + return obj.value; + } catch (Exception e) { + // throw the previous exception + throw me; + } + } + } catch (Exception e) { + throw new BSFException (BSFException.REASON_OTHER_ERROR, + e.getMessage (), e); + } + } + + /** + * Given a class return the type signature string fragment for it. + * That is, return "I" for int, "J" for long, ... etc.. + * + * @param cl class object for whom the signature fragment is needed. + * + * @return the string representing the type signature + */ + public static String getTypeSignatureString (Class cl) { + if (cl.isPrimitive ()) { + if (cl == boolean.class) + return "Z"; + else if (cl == byte.class) + return "B"; + else if (cl == char.class) + return "C"; + else if (cl == short.class) + return "S"; + else if (cl == int.class) + return "I"; + else if (cl == long.class) + return "J"; + else if (cl == float.class) + return "F"; + else if (cl == double.class) + return "D"; + else + return "V"; + } else { + StringBuffer sb = new StringBuffer ("L"); + sb.append (cl.getName ()); + sb.append (";"); + return sb.toString().replace ('.', '/'); + } + } + + /** + * Load a class using the class loader of given manager. If that fails + * try using a class loader that loads from the tempdir of the manager. + * + * @param mgr BSFManager who's classLoader and tempDir props are + * consulted + * @param name name of the class to load + * + * @return the loaded class + * + * @exception BSFException if something goes wrong. + */ + public static Class loadClass (BSFManager mgr, String name) + throws BSFException { + ClassLoader classLoader = mgr.getClassLoader (); + + try { + return (classLoader == null) ? + // Class.forName (name) + Thread.currentThread().getContextClassLoader().loadClass (name) + : classLoader.loadClass (name); + } catch (ClassNotFoundException e) { + // try to load it from the temp dir using my own class loader + try { + if (bsfCL == null) + bsfCL = new BSFClassLoader (); + bsfCL.setTempDir (mgr.getTempDir ()); + return bsfCL.loadClass (name); + } catch (ClassNotFoundException e2) { + throw new BSFException (BSFException.REASON_OTHER_ERROR, + "unable to load class '" + name + "':" + e, e); + } + } + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/IOUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/IOUtils.java new file mode 100644 index 000000000..45b5a0764 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/IOUtils.java @@ -0,0 +1,51 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.StringWriter; + +/** + * This file is a collection of input/output utilities. + * + * @author Sanjiva Weerawarana + * @author Matthew J. Duftler + */ +public class IOUtils { + // debug flag - generates debug stuff if true + static boolean debug = false; + + ////////////////////////////////////////////////////////////////////////// + + public static String getStringFromReader (Reader reader) throws IOException { + BufferedReader bufIn = new BufferedReader(reader); + StringWriter swOut = new StringWriter(); + PrintWriter pwOut = new PrintWriter(swOut); + String tempLine; + + while ((tempLine = bufIn.readLine()) != null) { + pwOut.println(tempLine); + } + + pwOut.flush(); + + return swOut.toString(); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/IndentWriter.java b/src/main/java/com/volmit/iris/util/bsf/util/IndentWriter.java new file mode 100644 index 000000000..7141bc041 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/IndentWriter.java @@ -0,0 +1,85 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.Writer; + +/** + * An IndentWriter object behaves the same as a + * PrintWriter object, with the additional capability + * of being able to print strings that are prepended with a specified + * amount of spaces. + * + * @author Matthew J. Duftler + */ +public class IndentWriter extends PrintWriter +{ + /** + * Forwards its arguments to the PrintWriter constructor + * with the same signature. + */ + public IndentWriter(OutputStream out) + { + super(out); + } + /** + * Forwards its arguments to the PrintWriter constructor + * with the same signature. + */ + public IndentWriter(OutputStream out, boolean autoFlush) + { + super(out, autoFlush); + } + /** + * Forwards its arguments to the PrintWriter constructor + * with the same signature. + */ + public IndentWriter(Writer out) + { + super(out); + } + /** + * Forwards its arguments to the PrintWriter constructor + * with the same signature. + */ + public IndentWriter(Writer out, boolean autoFlush) + { + super(out, autoFlush); + } + /** + * Print the text (indented the specified amount) without inserting a linefeed. + * + * @param numberOfSpaces the number of spaces to indent the text. + * @param text the text to print. + */ + public void print(int numberOfSpaces, String text) + { + super.print(StringUtils.getChars(numberOfSpaces, ' ') + text); + } + /** + * Print the text (indented the specified amount) and insert a linefeed. + * + * @param numberOfSpaces the number of spaces to indent the text. + * @param text the text to print. + */ + public void println(int numberOfSpaces, String text) + { + super.println(StringUtils.getChars(numberOfSpaces, ' ') + text); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.c b/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.c new file mode 100644 index 000000000..0c18b0cdc --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.c @@ -0,0 +1,228 @@ +/* + * Copyright 2003,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +#include "JNIUtils.h" + +/***** + * + * NOTE: Whereever I think an exception may occur, I need to check + * whether it did and recover appropriately .. otherwise the behavior + * of JNI is undefined! + * + *****/ + +/* throw a BSFException with the given code and message. */ +void bsf_exception (JNIEnv *jenv, int code, char *msg) { + jclass bsfexceptclass = + (*jenv)->FindClass (jenv, "org/apache/bsf/BSFException"); + (*jenv)->ThrowNew (jenv, bsfexceptclass, msg); +} + +/* cvt a pointer to a Long object whose value is the pointer value */ +jobject bsf_pointer2longobj (JNIEnv *jenv, void *ptr) { + return bsf_makeLong (jenv, (long) ptr); +} + +/* cvt a Long object whose value is the pointer value to the pointer */ +void *bsf_longobj2pointer (JNIEnv *jenv, jobject lobj) { + jclass longclass = (*jenv)->FindClass (jenv, "java/lang/Long"); + jmethodID mi = (*jenv)->GetMethodID (jenv, longclass, "longValue", "()J"); + void *ptr = (void *) (*jenv)->CallLongMethod (jenv, lobj, mi); + return ptr; +} + +/* convert an object to a string obj */ +jstring bsf_obj2jstring (JNIEnv *jenv, jobject obj) { + jclass objclass = (*jenv)->GetObjectClass (jenv, obj); + jmethodID tostr = (*jenv)->GetMethodID (jenv, objclass, "toString", + "()Ljava/lang/String;"); + jstring strobj = (jstring) (*jenv)->CallObjectMethod (jenv, obj, tostr); + return strobj; +} + +/* cvt an object to a c-string .. wastes memory, but useful for debug */ +const char *bsf_obj2cstring (JNIEnv *jenv, jobject obj) { + return (*jenv)->GetStringUTFChars (jenv, + bsf_obj2jstring (jenv, obj), + 0); +} + +/* call the named method with the given args on the given bean */ +jobject bsf_createbean (JNIEnv *jenv, char *classname, jobjectArray args) { + jclass cl; + jmethodID mid; + jobject result; + + /* find the BSFUtils.createBean method ID if needed */ + cl = (*jenv)->FindClass (jenv, "org/apache/bsf/util/EngineUtils"); + mid = (*jenv)->GetStaticMethodID (jenv, cl, "createBean", + "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); + if ((*jenv)->ExceptionOccurred (jenv)) { + (*jenv)->ExceptionDescribe (jenv); + (*jenv)->ExceptionClear (jenv); + return 0; + } + + result = (*jenv)->CallStaticObjectMethod (jenv, cl, mid, + (*jenv)->NewStringUTF (jenv, + classname), + args); + if ((*jenv)->ExceptionOccurred (jenv)) { + (*jenv)->ExceptionDescribe (jenv); + (*jenv)->ExceptionClear (jenv); + /* I should really throw a BSF exception here and the caller should + check whether an exception was thrown and in that case return. + later. */ + return 0; + } else { + return result; + } +} + +/* call the named method with the given args on the given bean */ +jobject bsf_callmethod (JNIEnv *jenv, jobject target, + char *methodname, jobjectArray args) { + jclass cl; + jmethodID mid; + jobject result; + + /* find the BSFUtils.callBeanMethod method ID if needed */ + cl = (*jenv)->FindClass (jenv, "org/apache/bsf/util/EngineUtils"); + mid = (*jenv)->GetStaticMethodID (jenv, cl, "callBeanMethod", + "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); + if ((*jenv)->ExceptionOccurred (jenv)) { + (*jenv)->ExceptionDescribe (jenv); + (*jenv)->ExceptionClear (jenv); + return 0; + } + result = (*jenv)->CallStaticObjectMethod (jenv, cl, mid, target, + (*jenv)->NewStringUTF (jenv, + methodname), + args); + if ((*jenv)->ExceptionOccurred (jenv)) { + (*jenv)->ExceptionDescribe (jenv); + (*jenv)->ExceptionClear (jenv); + /* I should really throw a BSF exception here and the caller should + check whether an exception was thrown and in that case return. + later. */ + return 0; + } else { + return result; + } +} + +/* return the named bean from the given mgr's bean registry */ +jobject bsf_lookupbean (JNIEnv *jenv, jobject mgr, char *beanname) { + jmethodID lookupMethod; + jobject result; + + jclass bsfmgrclass = (*jenv)->GetObjectClass (jenv, mgr); + lookupMethod = + (*jenv)->GetMethodID (jenv, bsfmgrclass, "lookupBean", + "(Ljava/lang/String;)Ljava/lang/Object;"); + if ((*jenv)->ExceptionOccurred (jenv)) { + (*jenv)->ExceptionDescribe (jenv); + (*jenv)->ExceptionClear (jenv); + return 0; + } + + result = (*jenv)->CallObjectMethod (jenv, mgr, lookupMethod, + (*jenv)->NewStringUTF (jenv, beanname)); + if ((*jenv)->ExceptionOccurred (jenv)) { + (*jenv)->ExceptionDescribe (jenv); + (*jenv)->ExceptionClear (jenv); + /* I should really throw a BSF exception here and the caller should + check whether an exception was thrown and in that case return. + later. */ + return 0; + } else { + return result; + } +} + +/* return the type signature string component for the given type: + I for ints, J for long, ... */ +char *bsf_getTypeSignatureString (JNIEnv *jenv, jclass objclass) { + jclass cl = 0; + jmethodID mid = 0; + jstring str; + + cl = (*jenv)->FindClass (jenv, "org/apache/bsf/util/EngineUtils"); + mid = (*jenv)->GetStaticMethodID (jenv, cl, "getTypeSignatureString", + "(Ljava/lang/Class;)Ljava/lang/String;"); + if ((*jenv)->ExceptionOccurred (jenv)) { + (*jenv)->ExceptionDescribe (jenv); + (*jenv)->ExceptionClear (jenv); + return 0; + } + str = (jstring) (*jenv)->CallStaticObjectMethod (jenv, cl, mid, objclass); + return (char *) bsf_obj2cstring (jenv, str); +} + +/* make objects from primitives */ + +jobject bsf_makeBoolean (JNIEnv *jenv, int val) { + jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Boolean"); + jmethodID constructor = + (*jenv)->GetMethodID (jenv, classobj, "", "(Z)V"); + return (*jenv)->NewObject (jenv, classobj, constructor, (jboolean) val); +} + +jobject bsf_makeByte (JNIEnv *jenv, int val) { + jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Byte"); + jmethodID constructor = + (*jenv)->GetMethodID (jenv, classobj, "", "(B)V"); + return (*jenv)->NewObject (jenv, classobj, constructor, (jbyte) val); +} + +jobject bsf_makeShort (JNIEnv *jenv, int val) { + jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Short"); + jmethodID constructor = + (*jenv)->GetMethodID (jenv, classobj, "", "(S)V"); + return (*jenv)->NewObject (jenv, classobj, constructor, (jshort) val); +} + +jobject bsf_makeInteger (JNIEnv *jenv, int val) { + jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Integer"); + jmethodID constructor = + (*jenv)->GetMethodID (jenv, classobj, "", "(I)V"); + return (*jenv)->NewObject (jenv, classobj, constructor, (jint) val); +} + +jobject bsf_makeLong (JNIEnv *jenv, long val) { + jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Long"); + jmethodID constructor = + (*jenv)->GetMethodID (jenv, classobj, "", "(J)V"); + return (*jenv)->NewObject (jenv, classobj, constructor, (jlong) val); +} + +jobject bsf_makeFloat (JNIEnv *jenv, float val) { + jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Float"); + jmethodID constructor = + (*jenv)->GetMethodID (jenv, classobj, "", "(F)V"); + return (*jenv)->NewObject (jenv, classobj, constructor, (jfloat) val); +} + +jobject bsf_makeDouble (JNIEnv *jenv, double val) { + jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Double"); + jmethodID constructor = + (*jenv)->GetMethodID (jenv, classobj, "", "(D)V"); + return (*jenv)->NewObject (jenv, classobj, constructor, (jdouble) val); +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.h b/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.h new file mode 100644 index 000000000..ffc83f65c --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.h @@ -0,0 +1,62 @@ +/* + * Copyright 2003,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#if defined(__cplusplus) +extern "C" { +#endif + +/* throw a BSFException with the given message */ +extern void bsf_exception (JNIEnv *jenv, int code, char *msg); + +/* cvt a pointer to a Long object whose value is the pointer value */ +extern jobject bsf_pointer2longobj (JNIEnv *jenv, void *ptr); + +/* cvt a Long object whose value is the pointer value to the pointer */ +extern void *bsf_longobj2pointer (JNIEnv *jenv, jobject lobj); + +/* convert an object to a string obj */ +jstring bsf_obj2jstring (JNIEnv *jenv, jobject obj); + +/* cvt an object to a c-string .. wastes memory, but useful for debug */ +const char *bsf_obj2cstring (JNIEnv *jenv, jobject obj); + +/* create an instance of the named class with the given args */ +extern jobject bsf_createbean (JNIEnv *jenv, char *methodname, + jobjectArray args); + +/* call the named method with the given args on the given bean */ +extern jobject bsf_callmethod (JNIEnv *jenv, jobject target, + char *methodname, jobjectArray args); + +/* return the named bean from the given mgr's bean registry */ +extern jobject bsf_lookupbean (JNIEnv *jenv, jobject mgr, char *beanname); + +/* return the type signature string component for the given type: + I for ints, J for long, ... */ +extern char *bsf_getTypeSignatureString (JNIEnv *jenv, jclass objclass); + +/* make objects from primitives */ +extern jobject bsf_makeBoolean (JNIEnv *jenv, int val); +extern jobject bsf_makeByte (JNIEnv *jenv, int val); +extern jobject bsf_makeShort (JNIEnv *jenv, int val); +extern jobject bsf_makeInteger (JNIEnv *jenv, int val); +extern jobject bsf_makeLong (JNIEnv *jenv, long val); +extern jobject bsf_makeFloat (JNIEnv *jenv, float val); +extern jobject bsf_makeDouble (JNIEnv *jenv, double val); +#if defined(__cplusplus) +} +#endif diff --git a/src/main/java/com/volmit/iris/util/bsf/util/JavaUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/JavaUtils.java new file mode 100644 index 000000000..f978a6548 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/JavaUtils.java @@ -0,0 +1,55 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class JavaUtils { + // Temporarily copied from JavaEngine... + + private static Log logger; + + static { + logger = LogFactory.getLog((com.volmit.iris.util.bsf.util.JavaUtils.class) + .getName()); + } + + public static boolean JDKcompile(String fileName, String classPath) { + String option = (logger.isDebugEnabled()) ? "-g" : "-O"; + String args[] = { "javac", option, "-classpath", classPath, fileName }; + + logger.debug("JavaEngine: Compiling " + fileName); + logger.debug("JavaEngine: Classpath is " + classPath); + + try { + Process p = java.lang.Runtime.getRuntime().exec(args); + p.waitFor(); + return (p.exitValue() != 0); + } catch (IOException e) { + logger.error("ERROR: IO exception during exec(javac).", e); + } catch (SecurityException e) { + logger.error("ERROR: Unable to create subprocess to exec(javac).", + e); + } catch (InterruptedException e) { + logger.error("ERROR: Wait for exec(javac) was interrupted.", e); + } + return false; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/MethodUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/MethodUtils.java new file mode 100644 index 000000000..b3161a897 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/MethodUtils.java @@ -0,0 +1,517 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Enumeration; +import java.util.Vector; + +/** + * This file is a collection of reflection utilities for dealing with + * methods and constructors. + * + * @author Sanjiva Weerawarana + * @author Joseph Kesselman + */ +public class MethodUtils { + + /** Internal Class for getEntryPoint(). Implements 15.11.2.2 MORE + SPECIFIC rules. + + Retains a list of methods (already known to match the + arguments). As each method is added, we check against past entries + to determine which if any is "more specific" -- defined as having + _all_ its arguments (not just a preponderance) be + method-convertable into those of another. If such a relationship + is found, the more-specific method is retained and the + less-specific method is discarded. At the end, if this has yielded + a single winner it is considered the Most Specific Method and + hence the one that should be invoked. Otherwise, a + NoSuchMethodException is thrown. + + PERFORMANCE VERSUS ARCHITECTURE: Arguably, this should "have-a" + Vector. But the code is 6% smaller, and possibly faster, if we + code it as "is-a" Vector. Since it's an inner class, nobody's + likely to abuse the privilage. + + Note: "Static" in the case of an inner class means "Does not + reference instance data in the outer class", and is required since + our caller is a static method. */ + private static class MoreSpecific + extends Vector + { + /** Submit an entry-point to the list. May be discarded if a past + entry is more specific, or may cause others to be discarded it + if is more specific. + + newEntry: Method or Constructor under consideration. + */ + void addItem (Object newEntry) + { + if(size()==0) + addElement(newEntry); + else + { + Class[] newargs=entryGetParameterTypes(newEntry); + boolean keep=true; + for (Enumeration e = elements(); + keep & e.hasMoreElements() ; + ) + { + Object oldEntry=e.nextElement(); + // CAVEAT: Implicit references to enclosing class! + Class[] oldargs=entryGetParameterTypes(oldEntry); + if(areMethodConvertable(oldargs,newargs)) + removeElement(oldEntry); // New more specific; discard old + else if(areMethodConvertable(newargs,oldargs)) + keep=false; // Old more specific; discard new + // Else they're tied. Keep both and hope someone beats both. + } + if(keep) + addElement(newEntry); + } + } + + /** Obtain the single Most Specific entry-point. If there is no clear + winner, or if the list is empty, throw NoSuchMethodException. + + Arguments describe the call we were hoping to resolve. They are + used to throw a nice verbose exception if something goes wrong. + */ + Object getMostSpecific(Class targetClass,String methodName, + Class[] argTypes,boolean isStaticReference) + throws NoSuchMethodException + { + if(size()==1) + return firstElement(); + if(size()>1) + { + StringBuffer buf=new StringBuffer(); + Enumeration e=elements(); + buf.append(e.nextElement()); + while(e.hasMoreElements()) + buf.append(" and ").append(e.nextElement()); + throw new NoSuchMethodException (callToString(targetClass, + methodName, + argTypes, + isStaticReference)+ + " is ambiguous. It matches "+ + buf.toString()); + } + return null; + } + } + + /** Convenience method: Test an entire parameter-list/argument-list pair + for isMethodConvertable(), qv. + */ + static private boolean areMethodConvertable(Class[] parms,Class[] args) + { + if(parms.length!=args.length) + return false; + + for(int i=0;i0) { + if(false) + { + // ????? Sanjiva has an ArrayToString method. Using it would + // save a few bytes, at cost of giving up some reusability. + } + else + { + buf.append(StringUtils.getClassName(argTypes[0])); + for (int i = 1; i < argTypes.length; i++) { + buf.append(",").append(StringUtils.getClassName(argTypes[i])); + } + } + } + else + buf.append("[none]"); + buf.append(")"); + return buf.toString(); + } + /** Utility function: obtain common data from either Method or + Constructor. (In lieu of an EntryPoint interface.) */ + static int entryGetModifiers(Object entry) + { + return (entry instanceof Method) + ? ((Method)entry).getModifiers() + : ((Constructor)entry).getModifiers(); + } + // The common lookup code would be much easier if Method and + // Constructor shared an "EntryPoint" Interface. Unfortunately, even + // though their APIs are almost identical, they don't. These calls + // are a workaround... at the cost of additional runtime overhead + // and some extra bytecodes. + // + // (A JDK bug report has been submitted requesting that they add the + // Interface; it would be easy, harmless, and useful.) + + /** Utility function: obtain common data from either Method or + Constructor. (In lieu of an EntryPoint interface.) */ + static String entryGetName(Object entry) + { + return (entry instanceof Method) + ? ((Method)entry).getName() + : ((Constructor)entry).getName(); + } + /** Utility function: obtain common data from either Method or + Constructor. (In lieu of an EntryPoint interface.) */ + static Class[] entryGetParameterTypes(Object entry) + { + return (entry instanceof Method) + ? ((Method)entry).getParameterTypes() + : ((Constructor)entry).getParameterTypes(); + } + /** Utility function: obtain common data from either Method or + Constructor. (In lieu of an EntryPoint interface.) */ + static String entryToString(Object entry) + { + return (entry instanceof Method) + ? ((Method)entry).toString() + : ((Constructor)entry).toString(); + } + ////////////////////////////////////////////////////////////////////////// + + /** Class.getConstructor() finds only the entry point (if any) + _exactly_ matching the specified argument types. Our implmentation + can decide between several imperfect matches, using the same + search algorithm as the Java compiler. + + Note that all constructors are static by definition, so + isStaticReference is true. + + @exception NoSuchMethodException if constructor not found. + */ + static public Constructor getConstructor(Class targetClass, Class[] argTypes) + throws SecurityException, NoSuchMethodException + { + return (Constructor) getEntryPoint(targetClass,null,argTypes,true); + } + ////////////////////////////////////////////////////////////////////////// + + /** + * Search for entry point, per Java Language Spec 1.0 + * as amended, verified by comparison against compiler behavior. + * + * @param targetClass Class object for the class to be queried. + * @param methodName Name of method to invoke, or null for constructor. + * Only Public methods will be accepted. + * @param argTypes Classes of intended arguments. Note that primitives + * must be specified via their TYPE equivalents, + * rather than as their wrapper classes -- Integer.TYPE + * rather than Integer. "null" may be passed in as an + * indication that you intend to invoke the method with + * a literal null argument and therefore can accept + * any object type in this position. + * @param isStaticReference If true, and if the target is a Class object, + * only static methods will be accepted as valid matches. + * + * @return a Method or Constructor of the appropriate signature + * + * @exception SecurityException if security violation + * @exception NoSuchMethodException if no such method + */ + static private Object getEntryPoint(Class targetClass, + String methodName, + Class[] argTypes, + boolean isStaticReference) + throws SecurityException, NoSuchMethodException + { + // 15.11.1: OBTAIN STARTING CLASS FOR SEARCH + Object m=null; + + // 15.11.2 DETERMINE ARGUMENT SIGNATURE + // (Passed in as argTypes array.) + + // Shortcut: If an exact match exists, return it. + try { + if(methodName!=null) + { + m=targetClass.getMethod (methodName, argTypes); + if(isStaticReference && + !Modifier.isStatic(entryGetModifiers(m)) ) + { + throw + new NoSuchMethodException (callToString (targetClass, + methodName, + argTypes, + isStaticReference)+ + " resolved to instance " + m); + } + return m; + } + else + return targetClass.getConstructor (argTypes); + + } catch (NoSuchMethodException e) { + // no-args has no alternatives! + if(argTypes==null || argTypes.length==0) + { + throw + new NoSuchMethodException (callToString (targetClass, + methodName, + argTypes, + isStaticReference)+ + " not found."); + } + // Else fall through. + } + + // Well, _that_ didn't work. Time to search for the Most Specific + // matching function. NOTE that conflicts are possible! + + // 15.11.2.1 ACCESSIBLE: We apparently need to gather from two + // sources to be sure we have both instance and static methods. + Object[] methods; + if(methodName!=null) + { + methods=targetClass.getMethods(); + } + else + { + methods=targetClass.getConstructors(); + } + if(0==methods.length) + { + throw new NoSuchMethodException("No methods!"); + } + + MoreSpecific best=new MoreSpecific(); + for(int i=0;i=primTypes.length) + return false; // Off the end + + for(argscore=0;argscore=primTypes.length) + return false; // Off the end + + // OK if ordered AND NOT char-to-smaller-than-int + return (argscore2) ); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/ObjInfo.java b/src/main/java/com/volmit/iris/util/bsf/util/ObjInfo.java new file mode 100644 index 000000000..2546f86e3 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/ObjInfo.java @@ -0,0 +1,88 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +/** + * An ObjInfo object is used by a compiler to track the name and + * type of a bean. + * + * @author Matthew J. Duftler + */ +public class ObjInfo +{ + static private String QUOTE_CHARS = "\'\"", + EXEC_CHARS = "(="; + public String objName; + public Class objClass; + + public ObjInfo(Class objClass, String objName) + { + this.objClass = objClass; + this.objName = objName; + } + public boolean isExecutable() + { + char[] chars = objName.toCharArray(); + char openingChar = ' '; + boolean inString = false, + inEscapeSequence = false; + + for (int i = 0; i < chars.length; i++) + { + if (inEscapeSequence) + { + inEscapeSequence = false; + } + else if (QUOTE_CHARS.indexOf(chars[i]) != -1) + { + if (!inString) + { + openingChar = chars[i]; + inString = true; + } + else + { + if (chars[i] == openingChar) + { + inString = false; + } + } + } + else if (EXEC_CHARS.indexOf(chars[i]) != -1) + { + if (!inString) + { + return true; + } + } + else if (inString && chars[i] == '\\') + { + inEscapeSequence = true; + } + } + + return false; + } + public boolean isValueReturning() + { + return (objClass != void.class && objClass != Void.class); + } + public String toString() + { + return StringUtils.getClassName(objClass) + " " + objName; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/ObjectRegistry.java b/src/main/java/com/volmit/iris/util/bsf/util/ObjectRegistry.java new file mode 100644 index 000000000..af6b72267 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/ObjectRegistry.java @@ -0,0 +1,63 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.util.Hashtable; + +/** + * The ObjectRegistry is used to do name-to-object reference lookups. + * If an ObjectRegistry is passed as a constructor argument, then this + * ObjectRegistry will be a cascading registry: when a lookup is + * invoked, it will first look in its own table for a name, and if it's not + * there, it will cascade to the parent ObjectRegistry. + * All registration is always local. [??] + * + * @author Sanjiva Weerawarana + * @author Matthew J. Duftler + */ +public class ObjectRegistry { + Hashtable reg = new Hashtable (); + ObjectRegistry parent = null; + + public ObjectRegistry () { + } + public ObjectRegistry (ObjectRegistry parent) { + this.parent = parent; + } + // lookup an object: cascade up if needed + public Object lookup (String name) throws IllegalArgumentException { + Object obj = reg.get (name); + + if (obj == null && parent != null) { + obj = parent.lookup (name); + } + + if (obj == null) { + throw new IllegalArgumentException ("object '" + name + "' not in registry"); + } + + return obj; + } + // register an object + public void register (String name, Object obj) { + reg.put (name, obj); + } + // unregister an object (silent if unknown name) + public void unregister (String name) { + reg.remove (name); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/ReflectionUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/ReflectionUtils.java new file mode 100644 index 000000000..ae9e0c36a --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/ReflectionUtils.java @@ -0,0 +1,421 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.beans.BeanInfo; +import java.beans.Beans; +import java.beans.EventSetDescriptor; +import java.beans.FeatureDescriptor; +import java.beans.IndexedPropertyDescriptor; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import com.volmit.iris.util.bsf.util.event.EventAdapter; +import com.volmit.iris.util.bsf.util.event.EventAdapterRegistry; +import com.volmit.iris.util.bsf.util.event.EventProcessor; +import com.volmit.iris.util.bsf.util.type.TypeConvertor; +import com.volmit.iris.util.bsf.util.type.TypeConvertorRegistry; + +/** + * This file is a collection of reflection utilities. There are utilities + * for creating beans, getting bean infos, setting/getting properties, + * and binding events. + * + * @author Sanjiva Weerawarana + * @author Joseph Kesselman + */ +public class ReflectionUtils { + + ////////////////////////////////////////////////////////////////////////// + + /** + * Add an event processor as a listener to some event coming out of an + * object. + * + * @param source event source + * @param eventSetName name of event set from event src to bind to + * @param processor event processor the event should be delegated to + * when it occurs; either via processEvent or + * processExceptionableEvent. + * + * @exception IntrospectionException if unable to introspect + * @exception IllegalArgumentException if event set is unknown + * @exception IllegalAccessException if the event adapter class or + * initializer is not accessible. + * @exception InstantiationException if event adapter instantiation fails + * @exception InvocationTargetException if something goes wrong while + * running add event listener method + */ + public static void addEventListener (Object source, String eventSetName, + EventProcessor processor) + throws IntrospectionException, IllegalArgumentException, + IllegalAccessException, InstantiationException, + InvocationTargetException { + // find the event set descriptor for this event + BeanInfo bi = Introspector.getBeanInfo (source.getClass ()); + EventSetDescriptor esd = (EventSetDescriptor) + findFeatureByName ("event", eventSetName, bi.getEventSetDescriptors ()); + + if (esd == null) // no events found, maybe a proxy from OpenOffice.org? + { + throw new IllegalArgumentException ("event set '" + eventSetName + + "' unknown for source type '" + source.getClass () + "'"); + } + + // get the class object for the event + Class listenerType=esd.getListenerType(); // get ListenerType class object from EventSetDescriptor + + // find an event adapter class of the right type + Class adapterClass = EventAdapterRegistry.lookup (listenerType); + if (adapterClass == null) { + throw new IllegalArgumentException ("event adapter for listener type " + + "'" + listenerType + "' (eventset " + + "'" + eventSetName + "') unknown"); + } + + // create the event adapter and give it the event processor + EventAdapter adapter = (EventAdapter) adapterClass.newInstance (); + adapter.setEventProcessor (processor); + + // bind the adapter to the source bean + Method addListenerMethod; + Object[] args; + if (eventSetName.equals ("propertyChange") || + eventSetName.equals ("vetoableChange")) { + // In Java 1.2, beans may have direct listener adding methods + // for property and vetoable change events which take the + // property name as a filter to be applied at the event source. + // The filter property of the event processor should be used + // in this case to support the source-side filtering. + // + // ** TBD **: the following two lines need to change appropriately + addListenerMethod = esd.getAddListenerMethod (); + args = new Object[] {adapter}; + } + else + { + addListenerMethod = esd.getAddListenerMethod (); + args = new Object[] {adapter}; + } + addListenerMethod.invoke (source, args); + } + ////////////////////////////////////////////////////////////////////////// + + + /** + * Create a bean using given class loader and using the appropriate + * constructor for the given args of the given arg types. + + * @param cld the class loader to use. If null, Class.forName is used. + * @param className name of class to instantiate + * @param argTypes array of argument types + * @param args array of arguments + * + * @return the newly created bean + * + * @exception ClassNotFoundException if class is not loaded + * @exception NoSuchMethodException if constructor can't be found + * @exception InstantiationException if class can't be instantiated + * @exception IllegalAccessException if class is not accessible + * @exception IllegalArgumentException if argument problem + * @exception InvocationTargetException if constructor excepted + * @exception IOException if I/O error in beans.instantiate + */ + public static Bean createBean (ClassLoader cld, String className, + Class[] argTypes, Object[] args) + throws ClassNotFoundException, NoSuchMethodException, + InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, + IOException { + if (argTypes != null) { + // find the right constructor and use that to create bean + Class cl = (cld != null) ? cld.loadClass (className) + : Thread.currentThread().getContextClassLoader().loadClass (className); // rgf, 2006-01-05 + // : Class.forName (className); + + Constructor c = MethodUtils.getConstructor (cl, argTypes); + return new Bean (cl, c.newInstance (args)); + } else { + // create the bean with no args constructor + Object obj = Beans.instantiate (cld, className); + return new Bean (obj.getClass (), obj); + } + } + ////////////////////////////////////////////////////////////////////////// + + /** + * Create a bean using given class loader and using the appropriate + * constructor for the given args. Figures out the arg types and + * calls above. + + * @param cld the class loader to use. If null, Class.forName is used. + * @param className name of class to instantiate + * @param args array of arguments + * + * @return the newly created bean + * + * @exception ClassNotFoundException if class is not loaded + * @exception NoSuchMethodException if constructor can't be found + * @exception InstantiationException if class can't be instantiated + * @exception IllegalAccessException if class is not accessible + * @exception IllegalArgumentException if argument problem + * @exception InvocationTargetException if constructor excepted + * @exception IOException if I/O error in beans.instantiate + */ + public static Bean createBean (ClassLoader cld, String className, + Object[] args) + throws ClassNotFoundException, NoSuchMethodException, + InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, + IOException { + Class[] argTypes = null; + if (args != null) { + argTypes = new Class[args.length]; + for (int i = 0; i < args.length; i++) { + argTypes[i] = (args[i] != null) ? args[i].getClass () : null; + } + } + return createBean (cld, className, argTypes, args); + } + ////////////////////////////////////////////////////////////////////////// + + /** + * locate the item in the fds array whose name is as given. returns + * null if not found. + */ + private static + FeatureDescriptor findFeatureByName (String featureType, String name, + FeatureDescriptor[] fds) { + for (int i = 0; i < fds.length; i++) { + if (name.equals (fds[i].getName())) { + return fds[i]; + } + } + return null; + } + public static Bean getField (Object target, String fieldName) + throws IllegalArgumentException, IllegalAccessException { + // This is to handle how we do static fields. + Class targetClass = (target instanceof Class) + ? (Class) target + : target.getClass (); + + try { + Field f = targetClass.getField (fieldName); + Class fieldType = f.getType (); + + // Get the value and return it. + Object value = f.get (target); + return new Bean (fieldType, value); + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException ("field '" + fieldName + "' is " + + "unknown for '" + target + "'"); + } + } + ////////////////////////////////////////////////////////////////////////// + + /** + * Get a property of a bean. + * + * @param target the object whose prop is to be gotten + * @param propName name of the property to set + * @param index index to get (if property is indexed) + * + * @exception IntrospectionException if unable to introspect + * @exception IllegalArgumentException if problems with args: if the + * property is unknown, or if the property is given an index + * when its not, or if the property is not writeable, or if + * the given value cannot be assigned to the it (type mismatch). + * @exception IllegalAccessException if read method is not accessible + * @exception InvocationTargetException if read method excepts + */ + public static Bean getProperty (Object target, String propName, + Integer index) + throws IntrospectionException, IllegalArgumentException, + IllegalAccessException, InvocationTargetException { + // find the property descriptor + BeanInfo bi = Introspector.getBeanInfo (target.getClass ()); + PropertyDescriptor pd = (PropertyDescriptor) + findFeatureByName ("property", propName, bi.getPropertyDescriptors ()); + if (pd == null) { + throw new IllegalArgumentException ("property '" + propName + "' is " + + "unknown for '" + target + "'"); + } + + // get read method and type of property + Method rm; + Class propType; + if (index != null) { + // if index != null, then property is indexed - pd better be so too + if (!(pd instanceof IndexedPropertyDescriptor)) { + throw new IllegalArgumentException ("attempt to get non-indexed " + + "property '" + propName + + "' as being indexed"); + } + IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd; + rm = ipd.getIndexedReadMethod (); + propType = ipd.getIndexedPropertyType (); + } else { + rm = pd.getReadMethod (); + propType = pd.getPropertyType (); + } + + if (rm == null) { + throw new IllegalArgumentException ("property '" + propName + + "' is not readable"); + } + + // now get the value + Object propVal = null; + if (index != null) { + propVal = rm.invoke (target, new Object[] {index}); + } else { + propVal = rm.invoke (target, null); + } + return new Bean (propType, propVal); + } + public static void setField (Object target, String fieldName, Bean value, + TypeConvertorRegistry tcr) + throws IllegalArgumentException, IllegalAccessException { + // This is to handle how we do static fields. + Class targetClass = (target instanceof Class) + ? (Class) target + : target.getClass (); + + try { + Field f = targetClass.getField (fieldName); + Class fieldType = f.getType (); + + // type convert the value if necessary + Object fieldVal = null; + boolean okeydokey = true; + if (fieldType.isAssignableFrom (value.type)) { + fieldVal = value.value; + } else if (tcr != null) { + TypeConvertor cvtor = tcr.lookup (value.type, fieldType); + if (cvtor != null) { + fieldVal = cvtor.convert (value.type, fieldType, value.value); + } else { + okeydokey = false; + } + } else { + okeydokey = false; + } + if (!okeydokey) { + throw new IllegalArgumentException ("unable to assign '" + value.value + + "' to field '" + fieldName + "'"); + } + + // now set the value + f.set (target, fieldVal); + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException ("field '" + fieldName + "' is " + + "unknown for '" + target + "'"); + } + } + ////////////////////////////////////////////////////////////////////////// + + /** + * Set a property of a bean to a given value. + * + * @param target the object whose prop is to be set + * @param propName name of the property to set + * @param index index to set (if property is indexed) + * @param value the property value + * @param valueType the type of the above (needed when its null) + * @param tcr type convertor registry to use to convert value type to + * property type if necessary + * + * @exception IntrospectionException if unable to introspect + * @exception IllegalArgumentException if problems with args: if the + * property is unknown, or if the property is given an index + * when its not, or if the property is not writeable, or if + * the given value cannot be assigned to the it (type mismatch). + * @exception IllegalAccessException if write method is not accessible + * @exception InvocationTargetException if write method excepts + */ + public static void setProperty (Object target, String propName, + Integer index, Object value, + Class valueType, TypeConvertorRegistry tcr) + throws IntrospectionException, IllegalArgumentException, + IllegalAccessException, InvocationTargetException { + // find the property descriptor + BeanInfo bi = Introspector.getBeanInfo (target.getClass ()); + PropertyDescriptor pd = (PropertyDescriptor) + findFeatureByName ("property", propName, bi.getPropertyDescriptors ()); + if (pd == null) { + throw new IllegalArgumentException ("property '" + propName + "' is " + + "unknown for '" + target + "'"); + } + + // get write method and type of property + Method wm; + Class propType; + if (index != null) { + // if index != null, then property is indexed - pd better be so too + if (!(pd instanceof IndexedPropertyDescriptor)) { + throw new IllegalArgumentException ("attempt to set non-indexed " + + "property '" + propName + + "' as being indexed"); + } + IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd; + wm = ipd.getIndexedWriteMethod (); + propType = ipd.getIndexedPropertyType (); + } else { + wm = pd.getWriteMethod (); + propType = pd.getPropertyType (); + } + + if (wm == null) { + throw new IllegalArgumentException ("property '" + propName + + "' is not writeable"); + } + + // type convert the value if necessary + Object propVal = null; + boolean okeydokey = true; + if (propType.isAssignableFrom (valueType)) { + propVal = value; + } else if (tcr != null) { + TypeConvertor cvtor = tcr.lookup (valueType, propType); + if (cvtor != null) { + propVal = cvtor.convert (valueType, propType, value); + } else { + okeydokey = false; + } + } else { + okeydokey = false; + } + if (!okeydokey) { + throw new IllegalArgumentException ("unable to assign '" + value + + "' to property '" + propName + "'"); + } + + // now set the value + if (index != null) { + wm.invoke (target, new Object[] {index, propVal}); + } else { + wm.invoke (target, new Object[] {propVal}); + } + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/ScriptSymbolTable.java b/src/main/java/com/volmit/iris/util/bsf/util/ScriptSymbolTable.java new file mode 100644 index 000000000..358e365eb --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/ScriptSymbolTable.java @@ -0,0 +1,44 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.util.Hashtable; + +/** + * An ScriptSymbolTable object is used by a CodeBuffer + * object to implement nested scopes. + * + * @author Matthew J. Duftler + */ +class ScriptSymbolTable extends Hashtable +{ + private Hashtable parentTable; + + ScriptSymbolTable(Hashtable parentTable) + { + this.parentTable = parentTable; + } + public synchronized Object get(Object key) + { + Object ret = super.get(key); + + if (ret == null && parentTable != null) + ret = parentTable.get(key); + + return ret; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/StringUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/StringUtils.java new file mode 100644 index 000000000..b512ffc76 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/StringUtils.java @@ -0,0 +1,412 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util; + +import java.beans.Introspector; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.StringTokenizer; +import java.util.Vector; + +/** + * Deals with strings (probably need to elaborate some more). + * + * @author Matthew J. Duftler + */ +public class StringUtils +{ + public static final String lineSeparator = + System.getProperty("line.separator", "\n"); + public static final String lineSeparatorStr = cleanString(lineSeparator); + + public static String classNameToVarName(String className) + { + // Might represent an array. + int arrayDim = 0; + + while (className.endsWith("[]")) + { + className = className.substring(0, className.length() - 2); + arrayDim++; + } + + int iLastPeriod = className.lastIndexOf('.'); + String varName = Introspector.decapitalize( + iLastPeriod != -1 + ? className.substring(iLastPeriod + 1) + : className); + + if (arrayDim > 0) + { + varName += "_" + arrayDim + "D"; + } + + return getValidIdentifierName(varName); + } + // Ensure that escape sequences are passed through properly. + public static String cleanString(String str) + { + if (str == null) + return null; + else + { + char[] charArray = str.toCharArray(); + StringBuffer sBuf = new StringBuffer(); + + for (int i = 0; i < charArray.length; i++) + switch (charArray[i]) + { + case '\"' : sBuf.append("\\\""); + break; + case '\\' : sBuf.append("\\\\"); + break; + case '\n' : sBuf.append("\\n"); + break; + case '\r' : sBuf.append("\\r"); + break; + default : sBuf.append(charArray[i]); + break; + } + + return sBuf.toString(); + } + } + /** + * Get a string consisting of numberOfChars theChars. + * + * @return a string consisting of numberOfChars theChars. + */ + public static String getChars(int numberOfChars, char theChar) + { + if (numberOfChars <= 0) + return ""; + + StringBuffer sRet = new StringBuffer(numberOfChars); + + for (int i = 0; i < numberOfChars; i++) + sRet.append(theChar); + + return sRet.toString(); + } + /* + This method will return the correct name for a class object representing + a primitive, a single instance of a class, as well as n-dimensional arrays + of primitives or instances. This logic is needed to handle the string returned + from Class.getName(). If the class object represents a single instance (or + a primitive), Class.getName() returns the fully-qualified name of the class + and no further work is needed. However, if the class object represents an + array (of n dimensions), Class.getName() returns a Descriptor (the Descriptor + grammar is defined in section 4.3 of the Java VM Spec). This method will + parse the Descriptor if necessary. + */ + public static String getClassName(Class targetClass) + { + String className = targetClass.getName(); + + return targetClass.isArray() ? parseDescriptor(className) : className; + } + public static String getCommaListFromVector(Vector sourceVector) + { + StringBuffer strBuf = new StringBuffer(); + + for (int i = 0; i < sourceVector.size(); i++) + { + strBuf.append((i > 0 ? ", " : "") + + sourceVector.elementAt(i)); + } + + return strBuf.toString(); + } + /* + Returns a Reader for reading from the specified resource, if the resource + points to a stream. + */ + public static Reader getContentAsReader(URL url) throws SecurityException, + IllegalArgumentException, + IOException + { + if (url == null) + { + throw new IllegalArgumentException("URL cannot be null."); + } + + try + { + Object content = url.getContent(); + + if (content == null) + { + throw new IllegalArgumentException("No content."); + } + + if (content instanceof InputStream) + { + Reader in = new InputStreamReader((InputStream)content); + + if (in.ready()) + { + return in; + } + else + { + throw new FileNotFoundException(); + } + } + else + { + throw new IllegalArgumentException((content instanceof String) + ? (String)content + : "This URL points to a: " + + StringUtils.getClassName(content.getClass())); + } + } + catch (SecurityException e) + { + throw new SecurityException("Your JVM's SecurityManager has disallowed this."); + } + catch (FileNotFoundException e) + { + throw new FileNotFoundException("This file was not found: " + url); + } + } + /* + Shorthand for: IOUtils.getStringFromReader(getContentAsReader(url)). + */ + public static String getContentAsString(URL url) throws SecurityException, + IllegalArgumentException, + IOException + { + return IOUtils.getStringFromReader(getContentAsReader(url)); + } + // Handles multi-line strings. + public static String getSafeString(String scriptStr) + { + BufferedReader in = new BufferedReader(new StringReader(scriptStr)); + StringBuffer strBuf = new StringBuffer(); + String tempLine, + previousLine = null; + + try + { + while ((tempLine = in.readLine()) != null) + { + if (previousLine != null) + { + strBuf.append("\"" + previousLine + lineSeparatorStr + "\" +" + + lineSeparator); + } + + previousLine = cleanString(tempLine); + } + } + catch (IOException e) + { + } + + strBuf.append("\"" + (previousLine != null ? previousLine : "") + "\"" + + lineSeparator); + + return strBuf.toString(); + } + /* + */ + public static URL getURL(URL contextURL, String spec) throws MalformedURLException + { + return getURL(contextURL, spec, 1); + } + /* + The recursiveDepth argument is used to insure that the algorithm gives up + after hunting 2 levels up in the contextURL's path. + */ + private static URL getURL(URL contextURL, String spec, int recursiveDepth) + throws MalformedURLException + { + URL url = null; + + try + { + url = new URL(contextURL, spec); + + try + { + url.openStream(); + } + catch (IOException ioe1) + { + throw new MalformedURLException("This file was not found: " + url); + } + } + catch (MalformedURLException e1) + { + url = new URL("file", "", spec); + + try + { + url.openStream(); + } + catch (IOException ioe2) + { + if (contextURL != null) + { + String contextFileName = contextURL.getFile(); + String parentName = new File(contextFileName).getParent(); + + if (parentName != null && recursiveDepth < 3) + { + return getURL(new URL("file", "", parentName + '/'), + spec, + recursiveDepth + 1); + } + } + + throw new MalformedURLException("This file was not found: " + url); + } + } + + return url; + } + public static String getValidIdentifierName(String identifierName) + { + if (identifierName == null || identifierName.length() == 0) + return null; + + StringBuffer strBuf = new StringBuffer(); + + char[] chars = identifierName.toCharArray(); + + strBuf.append(Character.isJavaIdentifierStart(chars[0]) + ? chars[0] + : '_' + ); + + for (int i = 1; i < chars.length; i++) + { + strBuf.append(Character.isJavaIdentifierPart(chars[i]) + ? chars[i] + : '_' + ); + } + + return strBuf.toString(); + } + public static boolean isValidIdentifierName(String identifierName) + { + if (identifierName == null || identifierName.length() == 0) + return false; + + char[] chars = identifierName.toCharArray(); + + if (!Character.isJavaIdentifierStart(chars[0])) + return false; + + for (int i = 1; i < chars.length; i++) + if (!Character.isJavaIdentifierPart(chars[i])) + return false; + + return true; + } + public static boolean isValidPackageName(String packageName) + { + if (packageName == null) + return false; + else if (packageName.length() == 0) + // Empty is ok. + return true; + + StringTokenizer strTok = new StringTokenizer(packageName, ".", true); + + // Should have an odd number of tokens (including '.' delimiters). + if (strTok.countTokens() % 2 != 1) + return false; + + // Must start with a valid identifier name. + if (!isValidIdentifierName(strTok.nextToken())) + return false; + + // ... followed by 0 or more of ".ValidIdentifier". + while (strTok.hasMoreTokens()) + { + // Must be a '.'. + if (!strTok.nextToken().equals(".")) + return false; + + // Must be a valid identifier name. + if (strTok.hasMoreTokens()) + { + if (!isValidIdentifierName(strTok.nextToken())) + return false; + } + else + return false; + } + + return true; + } + /* + See the comment above for getClassName(targetClass)... + */ + private static String parseDescriptor(String className) + { + char[] classNameChars = className.toCharArray(); + int arrayDim = 0; + int i = 0; + + while (classNameChars[i] == '[') + { + arrayDim++; + i++; + } + + StringBuffer classNameBuf = new StringBuffer(); + + switch (classNameChars[i++]) + { + case 'B' : classNameBuf.append("byte"); + break; + case 'C' : classNameBuf.append("char"); + break; + case 'D' : classNameBuf.append("double"); + break; + case 'F' : classNameBuf.append("float"); + break; + case 'I' : classNameBuf.append("int"); + break; + case 'J' : classNameBuf.append("long"); + break; + case 'S' : classNameBuf.append("short"); + break; + case 'Z' : classNameBuf.append("boolean"); + break; + case 'L' : classNameBuf.append(classNameChars, + i, classNameChars.length - i - 1); + break; + } + + for (i = 0; i < arrayDim; i++) + classNameBuf.append("[]"); + + return classNameBuf.toString(); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/cf/CFDriver.java b/src/main/java/com/volmit/iris/util/bsf/util/cf/CFDriver.java new file mode 100644 index 000000000..90352395b --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/cf/CFDriver.java @@ -0,0 +1,196 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.cf; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; + +/** + * This is an example of how a CodeFormatter bean can be used. + *

+ * The CFDriver is a stand-alone tool that will instantiate a + * CodeFormatter bean, configure it according to your + * command-line arguments, and invoke the formatting. Since the + * default source of input is stdin, and the default + * target for output is stdout, a CFDriver + * can also be used as a filter. + * + * @see CodeFormatter + * + * @version 1.0 + * @author Matthew J. Duftler + */ +public class CFDriver +{ + /** + * Not used. + */ + public CFDriver() + { + } + /** + * A driver for CodeFormatter. + *

+ * Usage: + *

+	*  java org.apache.cf.CFDriver [args]
+	*

+ * args: + *

+ * [-in fileName] default: <STDIN> + * [-out fileName] default: <STDOUT> + * [-maxLine length] default: 74 + * [-step size] default: 2 + * [-delim group] default: (+ + * [-sdelim group] default: , + *

+ */ + public static void main(String[] argv) + { + if (argv.length % 2 == 0) + { + String inFile = null, + outFile = null, + maxLine = null, + indStep = null, + delim = null, + sDelim = null; + Reader in = null; + Writer out = null; + CodeFormatter cf = new CodeFormatter(); + + for (int i = 0; i < argv.length; i += 2) + { + if (argv[i].startsWith("-i")) + inFile = argv[i + 1]; + else if (argv[i].startsWith("-o")) + outFile = argv[i + 1]; + else if (argv[i].startsWith("-m")) + maxLine = argv[i + 1]; + else if (argv[i].startsWith("-st")) + indStep = argv[i + 1]; + else if (argv[i].startsWith("-d")) + delim = argv[i + 1]; + else if (argv[i].startsWith("-sd")) + sDelim = argv[i + 1]; + } + + if (inFile != null) + { + try + { + in = new FileReader(inFile); + } + catch (FileNotFoundException e) + { + printError("Cannot open input file: " + inFile); + + return; + } + } + else + { + in = new InputStreamReader(System.in); + } + + if (outFile != null) + { + try + { + out = new FileWriter(outFile); + } + catch (IOException e) + { + printError("Cannot open output file: " + outFile); + + return; + } + } + else + { + out = new OutputStreamWriter(System.out); + } + + if (maxLine != null) + { + try + { + cf.setMaxLineLength(Integer.parseInt(maxLine)); + } + catch (NumberFormatException nfe) + { + printError("Not a valid integer: " + maxLine); + + return; + } + } + + if (indStep != null) + { + try + { + cf.setIndentationStep(Integer.parseInt(indStep)); + } + catch (NumberFormatException nfe) + { + printError("Not a valid integer: " + indStep); + + return; + } + } + + if (delim != null) + cf.setDelimiters(delim); + + if (sDelim != null) + cf.setStickyDelimiters(sDelim); + + cf.formatCode(in, out); + } + else + printHelp(); + } + private static void printError(String errMsg) + { + System.err.println("ERROR: " + errMsg); + } + private static void printHelp() + { + System.out.println("Usage:"); + System.out.println(); + System.out.println(" java " + CFDriver.class.getName() + " [args]"); + System.out.println(); + System.out.println(" args:"); + System.out.println(); + System.out.println(" [-in fileName] default: "); + System.out.println(" [-out fileName] default: "); + System.out.println(" [-maxLine length] default: " + + CodeFormatter.DEFAULT_MAX); + System.out.println(" [-step size] default: " + + CodeFormatter.DEFAULT_STEP); + System.out.println(" [-delim group] default: " + + CodeFormatter.DEFAULT_DELIM); + System.out.println(" [-sdelim group] default: " + + CodeFormatter.DEFAULT_S_DELIM); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/cf/CodeFormatter.java b/src/main/java/com/volmit/iris/util/bsf/util/cf/CodeFormatter.java new file mode 100644 index 000000000..de3e17d2a --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/cf/CodeFormatter.java @@ -0,0 +1,372 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.cf; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; + +import com.volmit.iris.util.bsf.util.IndentWriter; +import com.volmit.iris.util.bsf.util.StringUtils; + +/** + * A CodeFormatter bean is used to format raw Java code. It + * indents, word-wraps, and replaces tab characters with an amount of space + * characters equal to the size of the indentationStep property. + * To create and use a CodeFormatter, you simply instantiate a + * new CodeFormatter bean, and invoke + * formatCode(Reader source, Writer target) with appropriate + * arguments. + * + * @version 1.0 + * @author Matthew J. Duftler + */ +public class CodeFormatter +{ + /** + * The default maximum line length. + */ + public static final int DEFAULT_MAX = 74; + /** + * The default size of the indentation step. + */ + public static final int DEFAULT_STEP = 2; + /** + * The default set of delimiters. + */ + public static final String DEFAULT_DELIM = "(+"; + /** + * The default set of sticky delimiters. + */ + public static final String DEFAULT_S_DELIM = ","; + + // Configurable Parameters + private int maxLineLength = DEFAULT_MAX; + private int indentationStep = DEFAULT_STEP; + private String delimiters = DEFAULT_DELIM; + private String stickyDelimiters = DEFAULT_S_DELIM; + + // Global Variables + private int indent; + private int hangingIndent; + private int origIndent; + private boolean inCPP_Comment; + + private void addTok(StringBuffer targetBuf, StringBuffer tokBuf, + IndentWriter out) + { + int tokLength = tokBuf.length(), + targetLength = targetBuf.length(); + + if (indent + targetLength + tokLength > maxLineLength) + { + if (targetLength == 0) + { + out.println(indent, tokBuf.toString()); + indent = hangingIndent; + targetBuf.setLength(0); + + return; + } + else + { + out.println(indent, targetBuf.toString().trim()); + indent = hangingIndent; + targetBuf.setLength(0); + } + } + + targetBuf.append(tokBuf.toString()); + + return; + } + /** + * Formats the code read from source, and writes the formatted + * code to target. + * + * @param source where to read the unformatted code from. + * @param target where to write the formatted code to. + */ + public void formatCode(Reader source, Writer target) + { + String line; + BufferedReader in = new BufferedReader(source); + IndentWriter out = new IndentWriter(new BufferedWriter(target), true); + + try + { + origIndent = 0; + inCPP_Comment = false; + + while ((line = in.readLine()) != null) + { + line = line.trim(); + + if (line.length() > 0) + { + indent = origIndent; + hangingIndent = indent + indentationStep; + printLine(line, out); + } + else + out.println(); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + } + /** + * Gets the set of delimiters. + * + * @return the set of delimiters. + * @see #setDelimiters + */ + public String getDelimiters() + { + return delimiters; + } + /** + * Gets the size of the indentation step. + * + * @return the size of the indentation step. + * @see #setIndentationStep + */ + public int getIndentationStep() + { + return indentationStep; + } + /** + * Gets the maximum line length. + * + * @return the maximum line length. + * @see #setMaxLineLength + */ + public int getMaxLineLength() + { + return maxLineLength; + } + /** + * Gets the set of sticky delimiters. + * + * @return the set of sticky delimiters. + * @see #setStickyDelimiters + */ + public String getStickyDelimiters() + { + return stickyDelimiters; + } + private void printLine(String line, IndentWriter out) + { + char[] source = line.toCharArray(); + char ch; + char quoteChar = ' '; + boolean inEscapeSequence = false; + boolean inString = false; + StringBuffer tokBuf = new StringBuffer(), + targetBuf = new StringBuffer(hangingIndent + line.length()); + + for (int i = 0; i < source.length; i++) + { + ch = source[i]; + + if (inEscapeSequence) + { + tokBuf.append(ch); + inEscapeSequence = false; + } + else + { + if (inString) + { + switch (ch) + { + case '\\' : + tokBuf.append('\\'); + inEscapeSequence = true; + break; + case '\'' : + case '\"' : + tokBuf.append(ch); + + if (ch == quoteChar) + { + addTok(targetBuf, tokBuf, out); + tokBuf.setLength(0); + inString = false; + } + break; + case 9 : // pass thru tab characters... + tokBuf.append(ch); + break; + default : + if (ch > 31) + tokBuf.append(ch); + break; + } + } + else // !inString + { + if (inCPP_Comment) + { + tokBuf.append(ch); + + if (ch == '/' && i > 0 && source[i - 1] == '*') + inCPP_Comment = false; + } + else + { + switch (ch) + { + case '/' : + tokBuf.append(ch); + + if (i > 0 && source[i - 1] == '/') + { + String tokStr = tokBuf.append(source, + i + 1, + source.length - (i + 1)).toString(); + + out.println(indent, targetBuf.append(tokStr).toString()); + + return; + } + break; + case '*' : + tokBuf.append(ch); + + if (i > 0 && source[i - 1] == '/') + inCPP_Comment = true; + break; + case '\'' : + case '\"' : + addTok(targetBuf, tokBuf, out); + tokBuf.setLength(0); + tokBuf.append(ch); + quoteChar = ch; + inString = true; + break; + case 9 : // replace tab characters... + tokBuf.append(StringUtils.getChars(indentationStep, ' ')); + break; + case '{' : + tokBuf.append(ch); + origIndent += indentationStep; + break; + case '}' : + tokBuf.append(ch); + origIndent -= indentationStep; + + if (i == 0) + indent = origIndent; + break; + default : + if (ch > 31) + { + if (delimiters.indexOf(ch) != -1) + { + addTok(targetBuf, tokBuf, out); + tokBuf.setLength(0); + tokBuf.append(ch); + } + else if (stickyDelimiters.indexOf(ch) != -1) + { + tokBuf.append(ch); + addTok(targetBuf, tokBuf, out); + tokBuf.setLength(0); + } + else + tokBuf.append(ch); + } + break; + } + } + } + } + } + + if (tokBuf.length() > 0) + addTok(targetBuf, tokBuf, out); + + String lastLine = targetBuf.toString().trim(); + + if (lastLine.length() > 0) + out.println(indent, lastLine); + } + /** + * Sets the set of delimiters; default set is "(+". + *

+ * Each character represents one delimiter. If a line is ready to be + * word-wrapped and a delimiter is encountered, the delimiter will + * appear as the first character on the following line. + * A quotation mark, " or ', opening a string + * is always a delimiter, whether you specify it or not. + * + * @param newDelimiters the new set of delimiters. + * @see #getDelimiters + */ + public void setDelimiters(String newDelimiters) + { + delimiters = newDelimiters; + } + /** + * Sets the size of the indentation step; default size is 2. + *

+ * This is the number of spaces that lines will be indented (when appropriate). + * + * @param newIndentationStep the new size of the indentation step. + * @see #getIndentationStep + */ + public void setIndentationStep(int newIndentationStep) + { + indentationStep = (newIndentationStep < 0 ? 0 : newIndentationStep); + } + /** + * Sets the (desired) maximum line length; default length is + * 74. + *

+ * If a token is longer than the requested maximum line length, + * then the line containing that token will obviously be longer + * than the desired maximum. + * + * @param newMaxLineLength the new maximum line length. + * @see #getMaxLineLength + */ + public void setMaxLineLength(int newMaxLineLength) + { + maxLineLength = (newMaxLineLength < 0 ? 0 : newMaxLineLength); + } + /** + * Sets the set of sticky delimiters; default set is ",". + *

+ * Each character represents one sticky delimiter. If a line is ready + * to be word-wrapped and a sticky delimiter is encountered, the sticky + * delimiter will appear as the last character on the current line. + * A quotation mark, " or ', closing a string + * is always a sticky delimiter, whether you specify it or not. + * + * @param newStickyDelimiters the new set of sticky delimiters. + * @see #getStickyDelimiters + */ + public void setStickyDelimiters(String newStickyDelimiters) + { + stickyDelimiters = newStickyDelimiters; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapter.java new file mode 100644 index 000000000..d5faaf2fd --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapter.java @@ -0,0 +1,35 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event; + +/** + * EventAdapter is the interface that all event adapters must + * implement in order to work with the automatic event adapter generation + * model. This interface requires that the adapter implement a method + * that allows setting the event processor delegated to process the event + * after the adapter has received the event from the event source. The + * task of any event adapter is to receive the event and then delegate it + * to the event processor assigned to it, using either + * eventProcessor.processEvent or eventProcessor.processExceptionableEvent. + * + * @author Sanjiva Weerawarana + * @author Matthew J. Duftler + * @see EventProcessor + */ +public interface EventAdapter { + public void setEventProcessor (EventProcessor eventProcessor); +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterImpl.java b/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterImpl.java new file mode 100644 index 000000000..5d2297388 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterImpl.java @@ -0,0 +1,35 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event; + +/** + * EventAdapterImpl is a default implementation of the EventAdapter + * interface that specific event adapters may choose to subclass from + * instead of implementing the interface themselves. Saves 5 lines of code + * mebbe. + * + * @author Sanjiva Weerawarana + * @author Matthew J. Duftler + * @see EventAdapter + */ +public class EventAdapterImpl implements EventAdapter { + protected EventProcessor eventProcessor; + + public void setEventProcessor (EventProcessor eventProcessor) { + this.eventProcessor = eventProcessor; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterRegistry.java b/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterRegistry.java new file mode 100644 index 000000000..1c9d6a7e9 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterRegistry.java @@ -0,0 +1,103 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event; + +import java.util.Hashtable; + +import com.volmit.iris.util.bsf.util.event.generator.EventAdapterGenerator; + +/** + * The EventAdapterRegistry is the registry of event adapters. + * If a desired adapter is not found, the adapter will be dynamically + * generated when lookup is attempted. Set the dynamic property + * to false to disable this feature. + *

+ * This implementation first looks for an adapter in its lookup table + * and if it doesn't find one looks for a standard implementation of + * that adapter in the com.volmit.iris.util.bsf.util.event.adapters package with a + * standard naming convention. The naming convention it assumes is the + * following: for event listener type a.b.c.FooListener, + * it loads an adapter of type + * com.volmit.iris.util.bsf.util.event.adapters.a_b_c_FooAdapter. + * If both the loading and the dynamic generation fail, then a + * null is returned. + *

+ * + * @author Sanjiva Weerawarana + * @author Matthew J. Duftler + * @see EventAdapter + */ +public class EventAdapterRegistry { + private static Hashtable reg = new Hashtable (); + private static ClassLoader cl = null; + private static String adapterPackage = "com.volmit.iris.util.bsf.util.event.adapters"; + private static String adapterSuffix = "Adapter"; + private static boolean dynamic = true; + + public static Class lookup (Class listenerType) { + String key = listenerType.getName().replace ('.', '_'); + Class adapterClass = (Class) reg.get (key); + + if (adapterClass == null) { + String en = key.substring (0, key.lastIndexOf ("Listener")); + String cn = adapterPackage + "." + en + adapterSuffix; + + try { + // Try to resolve one. + // adapterClass = (cl != null) ? cl.loadClass (cn) : Class.forName (cn); + adapterClass = (cl != null) ? cl.loadClass (cn) + : Thread.currentThread().getContextClassLoader().loadClass (cn); // rgf, 2006-01-05 + + } catch (ClassNotFoundException e) { + if (dynamic) { + // Unable to resolve one, try to generate one. + adapterClass = // if second argument is set to 'true', then the class file will be stored in the filesystem + EventAdapterGenerator.makeEventAdapterClass (listenerType, false); + } + } + + if (adapterClass != null) { + reg.put (key, adapterClass); + } + } + + return adapterClass; + } + public static void register (Class listenerType, Class eventAdapterClass) { + String key = listenerType.getName().replace('.', '_'); + reg.put (key, eventAdapterClass); + } + /** + * Class loader to use to load event adapter classes. + */ + public static void setClassLoader (ClassLoader cloader) { + cl = cloader; + } + /** + * Indicates whether or not to dynamically generate adapters; default is + * true. + *

+ * If the dynamic property is set to true, and the + * ClassLoader is unable to resolve an adapter, one will be + * dynamically generated. + * + * @param dynamic whether or not to dynamically generate adapters. + */ + public static void setDynamic (boolean dynamic) { + EventAdapterRegistry.dynamic = dynamic; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/EventProcessor.java b/src/main/java/com/volmit/iris/util/bsf/util/event/EventProcessor.java new file mode 100644 index 000000000..7b5db8ac7 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/EventProcessor.java @@ -0,0 +1,35 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event; + + +/** + * EventProcessor is the interface that event adapters use to + * delegate events they received to be delivered to the appropriate target. + * They can simply deliver the event using processEvent or, if the event + * can be excepted to, via processExceptionableEvent (in which case the + * adapter is expected to forward on an exception to the source bean). + * + * @author Sanjiva Weerawarana + * @author Matthew J. Duftler + * @see EventAdapter + */ +public interface EventProcessor { + public void processEvent (String filter, Object[] eventInfo); + public void processExceptionableEvent (String filter, Object[] eventInfo) + throws Exception; +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ActionAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ActionAdapter.java new file mode 100644 index 000000000..2ff05d93e --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ActionAdapter.java @@ -0,0 +1,30 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_awt_event_ActionAdapter extends EventAdapterImpl + implements ActionListener { + + public void actionPerformed (ActionEvent e) { + eventProcessor.processEvent ("actionPerformed", new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_AdjustmentAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_AdjustmentAdapter.java new file mode 100644 index 000000000..b19e2092e --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_AdjustmentAdapter.java @@ -0,0 +1,30 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_awt_event_AdjustmentAdapter extends EventAdapterImpl + implements AdjustmentListener { + + public void adjustmentValueChanged (AdjustmentEvent e) { + eventProcessor.processEvent ("adjustmentValueChanged", new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ComponentAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ComponentAdapter.java new file mode 100644 index 000000000..2d5a0add4 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ComponentAdapter.java @@ -0,0 +1,39 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_awt_event_ComponentAdapter extends EventAdapterImpl + implements ComponentListener { + + public void componentHidden (ComponentEvent e) { + eventProcessor.processEvent ("componentHidden", new Object[]{e}); + } + public void componentMoved (ComponentEvent e) { + eventProcessor.processEvent ("componentMoved", new Object[]{e}); + } + public void componentResized (ComponentEvent e) { + eventProcessor.processEvent ("componentResized", new Object[]{e}); + } + public void componentShown (ComponentEvent e) { + eventProcessor.processEvent ("componentShown", new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ContainerAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ContainerAdapter.java new file mode 100644 index 000000000..74c935d5b --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ContainerAdapter.java @@ -0,0 +1,33 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.awt.event.ContainerEvent; +import java.awt.event.ContainerListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_awt_event_ContainerAdapter extends EventAdapterImpl + implements ContainerListener { + + public void componentAdded (ContainerEvent e) { + eventProcessor.processEvent ("componentAdded", new Object[]{e}); + } + public void componentRemoved (ContainerEvent e) { + eventProcessor.processEvent ("componentRemoved", new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_FocusAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_FocusAdapter.java new file mode 100644 index 000000000..a7740188d --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_FocusAdapter.java @@ -0,0 +1,33 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_awt_event_FocusAdapter extends EventAdapterImpl + implements FocusListener { + + public void focusGained (FocusEvent e) { + eventProcessor.processEvent ("focusGained", new Object[]{e}); + } + public void focusLost (FocusEvent e) { + eventProcessor.processEvent ("focusLost", new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ItemAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ItemAdapter.java new file mode 100644 index 000000000..9f7508110 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ItemAdapter.java @@ -0,0 +1,30 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_awt_event_ItemAdapter extends EventAdapterImpl + implements ItemListener { + + public void itemStateChanged (ItemEvent e) { + eventProcessor.processEvent ("itemStateChanged", new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_KeyAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_KeyAdapter.java new file mode 100644 index 000000000..21c3a7e2c --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_KeyAdapter.java @@ -0,0 +1,36 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_awt_event_KeyAdapter extends EventAdapterImpl + implements KeyListener { + + public void keyPressed (KeyEvent e) { + eventProcessor.processEvent ("keyPressed", new Object[]{e}); + } + public void keyReleased (KeyEvent e) { + eventProcessor.processEvent ("keyReleased", new Object[]{e}); + } + public void keyTyped (KeyEvent e) { + eventProcessor.processEvent ("keyTyped", new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseAdapter.java new file mode 100644 index 000000000..a0ec4950f --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseAdapter.java @@ -0,0 +1,42 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_awt_event_MouseAdapter extends EventAdapterImpl + implements MouseListener { + + public void mouseClicked (MouseEvent e) { + eventProcessor.processEvent ("mouseClicked", new Object[]{e}); + } + public void mouseEntered (MouseEvent e) { + eventProcessor.processEvent ("mouseEntered", new Object[]{e}); + } + public void mouseExited (MouseEvent e) { + eventProcessor.processEvent ("mouseExited", new Object[]{e}); + } + public void mousePressed (MouseEvent e) { + eventProcessor.processEvent ("mousePressed", new Object[]{e}); + } + public void mouseReleased (MouseEvent e) { + eventProcessor.processEvent ("mouseReleased", new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseMotionAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseMotionAdapter.java new file mode 100644 index 000000000..ec80769e3 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseMotionAdapter.java @@ -0,0 +1,33 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_awt_event_MouseMotionAdapter extends EventAdapterImpl + implements MouseMotionListener { + + public void mouseDragged(MouseEvent e) { + eventProcessor.processEvent ("mouseDragged", new Object[]{e}); + } + public void mouseMoved(MouseEvent e) { + eventProcessor.processEvent ("mouseMoved", new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_TextAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_TextAdapter.java new file mode 100644 index 000000000..f0ab8010a --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_TextAdapter.java @@ -0,0 +1,30 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.awt.event.TextEvent; +import java.awt.event.TextListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_awt_event_TextAdapter extends EventAdapterImpl + implements TextListener { + + public void textValueChanged (TextEvent e) { + eventProcessor.processEvent ("textValueChanged", new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_WindowAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_WindowAdapter.java new file mode 100644 index 000000000..866387eb3 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_WindowAdapter.java @@ -0,0 +1,48 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_awt_event_WindowAdapter extends EventAdapterImpl + implements WindowListener { + + public void windowActivated (WindowEvent e) { + eventProcessor.processEvent ("windowActivated", new Object[]{e}); + } + public void windowClosed (WindowEvent e) { + eventProcessor.processEvent ("windowClosed", new Object[]{e}); + } + public void windowClosing (WindowEvent e) { + eventProcessor.processEvent ("windowClosing", new Object[]{e}); + } + public void windowDeactivated (WindowEvent e) { + eventProcessor.processEvent ("windowDeactivated", new Object[]{e}); + } + public void windowDeiconified (WindowEvent e) { + eventProcessor.processEvent ("windowDeiconified", new Object[]{e}); + } + public void windowIconified (WindowEvent e) { + eventProcessor.processEvent ("windowIconified", new Object[]{e}); + } + public void windowOpened (WindowEvent e) { + eventProcessor.processEvent ("windowOpened", new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_PropertyChangeAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_PropertyChangeAdapter.java new file mode 100644 index 000000000..9adbf4884 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_PropertyChangeAdapter.java @@ -0,0 +1,30 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_beans_PropertyChangeAdapter extends EventAdapterImpl + implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent e) { + eventProcessor.processEvent (e.getPropertyName(), new Object[]{e}); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_VetoableChangeAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_VetoableChangeAdapter.java new file mode 100644 index 000000000..aafa64a98 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_VetoableChangeAdapter.java @@ -0,0 +1,41 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.adapters; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; + +import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; + +public class java_beans_VetoableChangeAdapter extends EventAdapterImpl + implements VetoableChangeListener { + + public void vetoableChange (PropertyChangeEvent e) throws PropertyVetoException { + try + { + eventProcessor.processExceptionableEvent (e.getPropertyName(), new Object[]{e}); + } + catch (PropertyVetoException ex) + { + throw ex; + } + catch (Exception ex) + { + } + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/AdapterClassLoader.java b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/AdapterClassLoader.java new file mode 100644 index 000000000..59dec6c66 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/AdapterClassLoader.java @@ -0,0 +1,102 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.generator; + +import java.util.Hashtable; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class AdapterClassLoader extends ClassLoader +{ + private static Hashtable classCache = new Hashtable(); + private Class c; + + private Log logger = LogFactory.getLog(this.getClass().getName()); + + public AdapterClassLoader() + { + super(); + } + public synchronized Class defineClass(String name, byte[] b) + { + if ((c = getLoadedClass(name)) == null) + { + c = defineClass(name.replace('/','.'), b, 0, b.length); // rgf, 2006-02-03 + put(name, c); + } + else + { + logger.error("AdapterClassLoader: " + c + + " previously loaded. Can not redefine class."); + } + + return c; + } + final protected Class findClass(String name) + { + return get(name); + } + final protected Class get(String name) + { + return (Class)classCache.get(name); + } + public synchronized Class getLoadedClass(String name) + { + Class c = findLoadedClass(name); + + if (c == null) + { + try + { + c = findSystemClass(name); + } + catch (ClassNotFoundException e) + { + } + } + + if (c == null) + { + c = findClass(name); + } + + return c; + } + protected synchronized Class loadClass(String name, boolean resolve) + throws ClassNotFoundException + { + Class c = getLoadedClass(name); + + if (c != null && resolve) + { + resolveClass(c); + } + + return c; + } + // Not in JDK 1.1, only in JDK 1.2. +// public AdapterClassLoader(ClassLoader loader) +// { +// super(loader); +// } + + final protected void put(String name, Class c) + { + classCache.put(name, c); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/ByteUtility.java b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/ByteUtility.java new file mode 100644 index 000000000..1412696cf --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/ByteUtility.java @@ -0,0 +1,331 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.generator; + +/** + * Byte handling utilities + * + * 5 April 1999 - functions to append standard types to byte arrays + * functions to produce standard types from byte arrays + * + * @author Richard F. Boehme + * + */ +public class ByteUtility +{ + public static byte[] addBytes(byte[] array,byte[] value) + { + if( null != array ) + { + byte newarray[] = new byte[array.length + value.length]; + System.arraycopy(array,0,newarray,0,array.length); + System.arraycopy(value,0,newarray,array.length,value.length); + array = newarray; + } + else + { + array = value; + } + return array; + } + public static byte[] addBytes(byte[] array, byte value) + { + if( null != array ) + { + byte newarray[] = new byte[array.length + 1]; + System.arraycopy(array,0,newarray,0,array.length); + newarray[newarray.length-1] = value; + array = newarray; + } + else + { + array = new byte[1]; + array[0] = value; + } + return array; + } + public static byte[] addBytes(byte[] array, int value) + { + if( null != array ) + { + byte newarray[] = new byte[array.length + 3]; + System.arraycopy(array,0,newarray,0,array.length); + newarray[newarray.length-3] = (byte) (( value >> 16 ) & 0xFF); + newarray[newarray.length-2] = (byte) (( value >> 8 ) & 0xFF); + newarray[newarray.length-1] = (byte) ( value & 0xFF); + array = newarray; + } + else + { + array = new byte[3]; + array[0] = (byte) (( value >> 16 ) & 0xFF); + array[1] = (byte) (( value >> 8 ) & 0xFF); + array[2] = (byte) ( value & 0xFF); + } + return array; + } + public static byte[] addBytes(byte[] array, long value) + { + if( null != array ) + { + byte newarray[] = new byte[array.length + 4]; + System.arraycopy(array,0,newarray,0,array.length); + newarray[newarray.length-4] = (byte) (( value >> 24 ) & 0xFF); + newarray[newarray.length-3] = (byte) (( value >> 16 ) & 0xFF); + newarray[newarray.length-2] = (byte) (( value >> 8 ) & 0xFF); + newarray[newarray.length-1] = (byte) ( value & 0xFF); + array = newarray; + } + else + { + array = new byte[4]; + array[0] = (byte) (( value >> 24 ) & 0xFF); + array[1] = (byte) (( value >> 16 ) & 0xFF); + array[2] = (byte) (( value >> 8 ) & 0xFF); + array[3] = (byte) (value & 0xFF); + } + return array; + } + public static byte[] addBytes(byte[] array,String value) + { + if( null != value ) + { + if( null != array) + { + byte newarray[] = new byte[array.length + value.length()]; + System.arraycopy(array,0,newarray,0,array.length); + System.arraycopy(value.getBytes(),0,newarray,array.length,value.length()); + array = newarray; + } + else + { + array = value.getBytes(); + } + } + return array; + } + public static byte[] addBytes(byte[] array, short value) + { + if( null != array) + { + byte newarray[] = new byte[array.length + 2]; + System.arraycopy(array,0,newarray,0,array.length); + newarray[newarray.length-2] = (byte) (( value >> 8 ) & 0xFF); + newarray[newarray.length-1] = (byte) ( value & 0xFF); + array = newarray; + } + else + { + array = new byte[2]; + array[0] = (byte) (( value >> 8 ) & 0xFF); + array[1] = (byte) ( value & 0xFF); + } + return array; + } + public static double byteArrayToDouble(byte high[], byte low[]) + { + double temp = 0; + // high bytes + temp += (((long)high[0]) & 0xFF) << 56; + temp += (((long)high[1]) & 0xFF) << 48; + temp += (((long)high[2]) & 0xFF) << 40; + temp += (((long)high[3]) & 0xFF) << 32; + // low bytes + temp += (((long)low[0]) & 0xFF) << 24; + temp += (((long)low[1]) & 0xFF) << 16; + temp += (((long)low[2]) & 0xFF) << 8; + temp += (((long)low[3]) & 0xFF); + return temp; + } + public static double byteArrayToDouble(byte value[]) + { + byte high[] = new byte[4]; + byte low[] = new byte[4]; + high[0] = value[0]; + high[1] = value[1]; + high[2] = value[2]; + high[3] = value[3]; + low[0] = value[4]; + low[1] = value[5]; + low[2] = value[6]; + low[3] = value[7]; + return byteArrayToDouble(high,low); + } + public static float byteArrayToFloat(byte value[]) + { + float temp = 0; + temp += (((int)value[0]) & 0xFF) << 24; + temp += (((int)value[1]) & 0xFF) << 16; + temp += (((int)value[2]) & 0xFF) << 8; + temp += (((int)value[3]) & 0xFF); + return temp; + } + public static int byteArrayToInt(byte value[]) + { + int temp = 0; + temp += (((int)value[0]) & 0xFF) << 24; + temp += (((int)value[1]) & 0xFF) << 16; + temp += (((int)value[2]) & 0xFF) << 8; + temp += (((int)value[3]) & 0xFF); + return temp; + } + public static long byteArrayToLong(byte value[]) + { + byte high[] = new byte[4]; + byte low[] = new byte[4]; + high[0] = value[0]; + high[1] = value[1]; + high[2] = value[2]; + high[3] = value[3]; + low[0] = value[4]; + low[1] = value[5]; + low[2] = value[6]; + low[3] = value[7]; + return byteArrayToLong(high,low); + } + public static long byteArrayToLong(byte high[], byte low[]) + { + long temp = 0; + // high bytes + temp += (((long)high[0]) & 0xFF) << 56; + temp += (((long)high[1]) & 0xFF) << 48; + temp += (((long)high[2]) & 0xFF) << 40; + temp += (((long)high[3]) & 0xFF) << 32; + // low bytes + temp += (((long)low[0]) & 0xFF) << 24; + temp += (((long)low[1]) & 0xFF) << 16; + temp += (((long)low[2]) & 0xFF) << 8; + temp += (((long)low[3]) & 0xFF); + return temp; + } + // make the following loops with check on array length ***************** + public static short byteArrayToShort(byte value[]) + { + short temp = 0; + temp += (((int)value[0]) & 0xFF) << 8; + temp += (((int)value[1]) & 0xFF); + return temp; + } + public static String byteToHexString(byte value) + { + String temp = null; + + switch( (value & 0xF0) >> 4 ) + { + case 0: + temp = "0"; + break; + case 1: + temp = "1"; + break; + case 2: + temp = "2"; + break; + case 3: + temp = "3"; + break; + case 4: + temp = "4"; + break; + case 5: + temp = "5"; + break; + case 6: + temp = "6"; + break; + case 7: + temp = "7"; + break; + case 8: + temp = "8"; + break; + case 9: + temp = "9"; + break; + case 10: + temp = "A"; + break; + case 11: + temp = "B"; + break; + case 12: + temp = "C"; + break; + case 13: + temp = "D"; + break; + case 14: + temp = "E"; + break; + case 15: + temp = "F"; + break; + } + switch( (value & 0x0F) ) + { + case 0: + temp += "0"; + break; + case 1: + temp += "1"; + break; + case 2: + temp += "2"; + break; + case 3: + temp += "3"; + break; + case 4: + temp += "4"; + break; + case 5: + temp += "5"; + break; + case 6: + temp += "6"; + break; + case 7: + temp += "7"; + break; + case 8: + temp += "8"; + break; + case 9: + temp += "9"; + break; + case 10: + temp += "A"; + break; + case 11: + temp += "B"; + break; + case 12: + temp += "C"; + break; + case 13: + temp += "D"; + break; + case 14: + temp += "E"; + break; + case 15: + temp += "F"; + break; + } + return temp; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/Bytecode.java b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/Bytecode.java new file mode 100644 index 000000000..f89846113 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/Bytecode.java @@ -0,0 +1,105 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.generator; + +/** + * Bytecode handling utilities + * + * Handle standard byte arrays as defined in Java VM and Class File + * + * 5 April 1999 - functions to append Class File byte subarrays + * into a Class File byte array + * + * @author Richard F. Boehme + * + */ +public class Bytecode +{ + // Constant Pool Item Codes + public static final byte C_Utf8 = 0x01; // 1 + public static final byte C_Integer = 0x03; // 3 + public static final byte C_Float = 0x04; // 4 + public static final byte C_Long = 0x05; // 5 + public static final byte C_Double = 0x06; // 6 + public static final byte C_Class = 0x07; // 7 + public static final byte C_String = 0x08; // 8 + public static final byte C_FieldRef = 0x09; // 9 + public static final byte C_MethodRef = 0x0A; // 10 + public static final byte C_InterfaceMethodRef = 0x0B; // 11 + public static final byte C_NameAndType = 0x0C; // 12 + +//public static byte[] addDouble(byte[] array,double value) +//{ +// array = ByteUtility.addBytes(array,C_Double); +// array = ByteUtility.addBytes(array,value); +// return array; +//} + + public static byte[] addClass(byte[] array,short value) + { return addRef(C_Class,array,value); } + public static byte[] addFieldRef(byte[] array,short value1,short value2) + { return addRef(C_FieldRef,array,value1,value2); } + public static byte[] addInteger(byte[] array,int value) + { + array = ByteUtility.addBytes(array,C_Integer); + array = ByteUtility.addBytes(array,value); + return array; + } + public static byte[] addInterfaceMethodRef(byte[] array,short value1,short value2) + { return addRef(C_InterfaceMethodRef,array,value1,value2); } +//public static byte[] addFloat(byte[] array,float value) +//{ +// array = ByteUtility.addBytes(array,C_Float); +// array = ByteUtility.addBytes(array,value); +// return array; +//} + + public static byte[] addLong(byte[] array,long value) + { + array = ByteUtility.addBytes(array,C_Long); + array = ByteUtility.addBytes(array,value); + return array; + } + public static byte[] addMethodRef(byte[] array,short value1,short value2) + { return addRef(C_MethodRef,array,value1,value2); } + public static byte[] addNameAndType(byte[] array,short value1,short value2) + { return addRef(C_NameAndType,array,value1,value2); } + public static byte[] addRef(byte refType,byte[] array,short value) + { + array = ByteUtility.addBytes(array,refType); + array = ByteUtility.addBytes(array,value); + return array; + } + // Generic Bytecode Methods + public static byte[] addRef(byte refType,byte[] array,short value1,short value2) + { + array = ByteUtility.addBytes(array,refType); + array = ByteUtility.addBytes(array,value1); + array = ByteUtility.addBytes(array,value2); + return array; + } + public static byte[] addString(byte[] array,short value) + { return addRef(C_String,array,value); } + // Constant Pool Item Methods + public static byte[] addUtf8(byte[] array,String value) + { + array = ByteUtility.addBytes(array,C_Utf8); + array = ByteUtility.addBytes(array,(short)value.length()); + array = ByteUtility.addBytes(array,value); + return array; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/EventAdapterGenerator.java b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/EventAdapterGenerator.java new file mode 100644 index 000000000..c38dcbe74 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/EventAdapterGenerator.java @@ -0,0 +1,568 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.event.generator; + +import java.io.FileOutputStream; +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** EventAdapterGenerator + * + * Generate an "Event Adapter" dynamically during program execution + * + **/ +public class EventAdapterGenerator +{ + public static AdapterClassLoader ldr = new AdapterClassLoader(); + static Class EVENTLISTENER = null; + static String CLASSPACKAGE = "org/apache/bsf/util/event/adapters/"; + static String WRITEDIRECTORY = null; + + // starting 8 bytes of all Java Class files + static byte CLASSHEADER[]; + // constant pool items found in all event adapters + static short BASECPCOUNT; // number of cp items + 1 ( cp item # 0 reserved for JVM ) + static byte BASECP[]; // + // some bytes in the middle of the class file (see below) + static byte FIXEDCLASSBYTES[]; + // the initialization method, noargs constructor + static byte INITMETHOD[]; + + private static Log logger; + + /* The static initializer */ + static + { + logger = LogFactory.getLog( + (com.volmit.iris.util.bsf.util.event.generator.EventAdapterGenerator.class).getName()); + + String USERCLASSPACKAGE = System.getProperty("DynamicEventClassPackage", + ""); + + if (!USERCLASSPACKAGE.equals("")) + { + CLASSPACKAGE = USERCLASSPACKAGE; + } + + if(CLASSPACKAGE.length() > 0 ) + { + CLASSPACKAGE = CLASSPACKAGE.replace('\\','/'); + if(!CLASSPACKAGE.endsWith("/")) + { CLASSPACKAGE = CLASSPACKAGE+"/"; } + } + WRITEDIRECTORY = System.getProperty("DynamicEventClassWriteDirectory",CLASSPACKAGE); + if(WRITEDIRECTORY.length() > 0 ) + { + WRITEDIRECTORY = WRITEDIRECTORY.replace('\\','/'); + if(!WRITEDIRECTORY.endsWith("/")) + { WRITEDIRECTORY = WRITEDIRECTORY+"/"; } + } + try + // { EVENTLISTENER = Class.forName("java.util.EventListener"); } + { EVENTLISTENER = Thread.currentThread().getContextClassLoader().loadClass ("java.util.EventListener"); } // rgf, 2006-01-05 + catch(ClassNotFoundException ex) + { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + } + + + // start of the Java Class File + CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xCA); // magic + CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xFE); // magic + CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xBA); // magic + CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xBE); // magic + CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(short)3); // minor version + CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(short)45); // major version + + // Start the constant pool for base items in all event adapter classes + BASECPCOUNT = 17; // number of cp items + 1 ( cp item # 0 reserved for JVM ) + + // cp item 01 + BASECP = Bytecode.addUtf8(BASECP,"()V"); + + // cp item 02 + BASECP = Bytecode.addUtf8(BASECP,""); + + // cp item 03 + BASECP = Bytecode.addUtf8(BASECP,"Code"); + + // cp item 04 + BASECP = Bytecode.addUtf8(BASECP,"eventProcessor"); + + // cp item 05 + BASECP = Bytecode.addUtf8(BASECP,"java/lang/Object"); + + // cp item 06 + BASECP = Bytecode.addUtf8(BASECP,"org/apache/bsf/util/event/EventAdapterImpl"); + + // cp item 07 + BASECP = Bytecode.addUtf8(BASECP,"org/apache/bsf/util/event/EventProcessor"); + + // cp item 08 + BASECP = Bytecode.addUtf8(BASECP,"(Ljava/lang/String;[Ljava/lang/Object;)V"); + + // cp item 09 + BASECP = Bytecode.addUtf8(BASECP,"Lorg/apache/bsf/util/event/EventProcessor;"); + + // cp item 10 + BASECP = Bytecode.addClass(BASECP,(short)5); // Class "java/lang/Object" + + // cp item 11 + BASECP = Bytecode.addClass(BASECP,(short)6); // Class "org/apache/bsf/util/event/EventAdapterImpl" + + // cp item 12 + BASECP = Bytecode.addClass(BASECP,(short)7); // Class "org/apache/bsf/util/event/EventProcessor" + + // cp item 13 + BASECP = Bytecode.addNameAndType(BASECP,(short)2,(short)1); // "" "()V" + + // cp item 14 + BASECP = Bytecode.addNameAndType(BASECP,(short)4,(short)9); // "eventProcessor" "Lorg/apache/bsf/util/event/EventProcessor;" + + // cp item 15 + BASECP = Bytecode.addFieldRef(BASECP,(short)11,(short)14); + + // cp item 16 + BASECP = Bytecode.addMethodRef(BASECP,(short)11,(short)13); + + // fixed bytes in middle of class file + FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)0x21); // access_flags (fixed) + FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)20); // this_class (fixed) + FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)11); // super_class (fixed) + FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)1); // interface_count (fixed) + FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)19); // interfaces (fixed) + FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)0); // field_count (fixed) + + // initialization method, constructor + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1); // access_flags + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)2); // name_index "" + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1); // descriptor_index "()V" + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1); // attribute_count + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)3); // attribute_name_index "Code" + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(long)17); // attribute_length + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1); // max_stack + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1); // max_locals + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(long)5); // code_length + //code + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(byte)0x2A); // aload_0 + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(byte)0xB7); // invokespecial + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)16); // method_ref index + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(byte)0xB1); // return + // exception table + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)0); // exception_table_length + INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)0); // attributes_count + + } + + /* methods that take an EventListener Class Type to create an EventAdapterClass */ + public static Class makeEventAdapterClass(Class listenerType,boolean writeClassFile) + { + logger.info("EventAdapterGenerator"); + + if( EVENTLISTENER.isAssignableFrom(listenerType) ) + { + boolean exceptionable = false; + boolean nonExceptionable = false; + byte constantPool[] = null; + short cpBaseIndex; + short cpCount = 0; + short cpExceptionBaseIndex; + short exceptionableCount; + short nonExceptionableCount; + + /* Derive Names */ + String listenerTypeName = listenerType.getName(); + logger.info("ListenerTypeName: "+listenerTypeName); + String adapterClassName = + CLASSPACKAGE+ + (listenerTypeName.endsWith("Listener") + ? listenerTypeName.substring(0, listenerTypeName.length() - 8) + : listenerTypeName).replace('.', '_') + + "Adapter"; + String finalAdapterClassName = adapterClassName; + Class cached = null; + int suffixIndex = 0; + + do + { + if (null != (cached = ldr.getLoadedClass(finalAdapterClassName))) + { + logger.info("cached: "+cached); + try + { + if (!listenerType.isAssignableFrom(cached)) + finalAdapterClassName = adapterClassName + "_" + suffixIndex++; + else + return cached; + } + catch(VerifyError ex) + { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + return cached; + } + } + } + while (cached != null); + + String eventListenerName = listenerTypeName.replace('.', '/'); + + /* method stuff */ + java.lang.reflect.Method lms[] = listenerType.getMethods(); + + /* ****************************************************************************************** */ + // Listener interface + // Class name + cpCount += 4; + + // cp item 17 + constantPool = Bytecode.addUtf8(constantPool,eventListenerName); + + // cp item 18 + constantPool = Bytecode.addUtf8(constantPool,finalAdapterClassName); + + // cp item 19 + constantPool = Bytecode.addClass(constantPool,(short)17); + + // cp item 20 + constantPool = Bytecode.addClass(constantPool,(short)18); + + // do we have nonExceptionalble event, exceptionable or both + for (int i = 0 ; i < lms.length ; ++i) + { + Class exceptionTypes[] = lms[i].getExceptionTypes(); + if( 0 < exceptionTypes.length) + { exceptionable = true; } + else + { nonExceptionable = true; } + }/* End for*/ + + /* ****************************************************************************************** */ + // optional inclusion of nonexceptional events affects exceptional events indices + + nonExceptionableCount = 0; + if(nonExceptionable) + { + nonExceptionableCount = 3; + cpCount += nonExceptionableCount; + + // cp item 21 + constantPool = Bytecode.addUtf8(constantPool,"processEvent"); + + // cp item 22 + constantPool = Bytecode.addNameAndType(constantPool,(short)21,(short)8); + + + // cp item 23 + constantPool = Bytecode.addInterfaceMethodRef(constantPool,(short)12,(short)22); + } + + /* ****************************************************************************************** */ + // optional inclusion of exceptional events affects CP Items which follow for specific methods + + exceptionableCount = 0; + if(exceptionable) + { + int classIndex = BASECPCOUNT + cpCount + 1; + int nameIndex = BASECPCOUNT + cpCount + 0; + int natIndex = BASECPCOUNT + cpCount + 3; + + exceptionableCount = 5; + cpCount += exceptionableCount; + + // cp item 24 or 21 + constantPool = Bytecode.addUtf8(constantPool,"processExceptionableEvent"); + + // cp item 25 or 22 + constantPool = Bytecode.addUtf8(constantPool,"java/lang/Exception"); + + // cp item 26 or 23 + constantPool = Bytecode.addClass(constantPool,(short)classIndex); + + // cp item 27 or 24 + constantPool = Bytecode.addNameAndType(constantPool,(short)nameIndex,(short)8); + + // cp item 28 or 25 + constantPool = Bytecode.addInterfaceMethodRef(constantPool,(short)12,(short)natIndex); + + } + + // base index for method cp references + cpBaseIndex = (short)(BASECPCOUNT + cpCount); + logger.debug("cpBaseIndex: " + cpBaseIndex); + + for (int i = 0 ; i < lms.length ; ++i) + { + String eventMethodName = lms[i].getName(); + String eventName = lms[i].getParameterTypes()[0].getName().replace('.','/'); + cpCount += 3; + // cp items for event methods + constantPool = Bytecode.addUtf8(constantPool,eventMethodName); + constantPool = Bytecode.addUtf8(constantPool,("(L" + eventName + ";)V")); + constantPool = Bytecode.addString(constantPool,(short)(BASECPCOUNT+cpCount-3)); + }/* End for*/ + + boolean propertyChangeFlag[] = new boolean[lms.length]; + int cpIndexPCE = 0; + for (int i = 0 ; i < lms.length ; ++i) + { + String eventName = lms[i].getParameterTypes()[0].getName().replace('.','/'); + // cp items for PropertyChangeEvent special handling + if(eventName.equalsIgnoreCase("java/beans/PropertyChangeEvent")) + { + propertyChangeFlag[i] = true; + if( 0 == cpIndexPCE ) + { + constantPool = Bytecode.addUtf8(constantPool,eventName); + constantPool = Bytecode.addUtf8(constantPool,"getPropertyName"); + constantPool = Bytecode.addUtf8(constantPool,"()Ljava/lang/String;"); + constantPool = Bytecode.addClass(constantPool,(short)(BASECPCOUNT + cpCount)); + constantPool = Bytecode.addNameAndType(constantPool, + (short)(BASECPCOUNT + cpCount + 1), + (short)(BASECPCOUNT + cpCount + 2)); + constantPool = Bytecode.addMethodRef(constantPool, + (short)(BASECPCOUNT + cpCount + 3), + (short)(BASECPCOUNT + cpCount + 4)); + cpCount += 6; + cpIndexPCE = BASECPCOUNT + cpCount - 1; + + } + } + else + { propertyChangeFlag[i] = false; } + }/* End for*/ + + cpExceptionBaseIndex = (short)(BASECPCOUNT + cpCount); + logger.debug("cpExceptionBaseIndex: " + cpExceptionBaseIndex); + + int excpIndex[][] = new int[lms.length][]; + for (int i = 0 ; i < lms.length ; ++i) + { + Class exceptionTypes[] = lms[i].getExceptionTypes(); + excpIndex[i] = new int[exceptionTypes.length]; + for ( int j = 0 ; j < exceptionTypes.length ; j++) + { + constantPool = Bytecode.addUtf8(constantPool,exceptionTypes[j].getName().replace('.', '/')); + constantPool = Bytecode.addClass(constantPool,(short)(BASECPCOUNT+cpCount)); + excpIndex[i][j] = BASECPCOUNT + cpCount + 1; + cpCount += 2; + } + }/* End for*/ + /* end constant pool */ + + /* ************************************************************************************************ */ + // put the Class byte array together + + /* start */ + byte newClass[] = CLASSHEADER; // magic, version (fixed) + short count = (short)(BASECPCOUNT + cpCount); + newClass = ByteUtility.addBytes(newClass,count); // constant_pool_count (variable) + newClass = ByteUtility.addBytes(newClass,BASECP); // constant_pool (fixed) + newClass = ByteUtility.addBytes(newClass,constantPool); // constant_pool (variable) + newClass = ByteUtility.addBytes(newClass,FIXEDCLASSBYTES); // see FIXEDCLASSBYTES (fixed) + newClass = ByteUtility.addBytes(newClass,(short)(lms.length+1)); // method_count (variable) + newClass = ByteUtility.addBytes(newClass,INITMETHOD); // constructor (fixed) + // methods + + /* ****************************************************************************************** */ + /* loop over listener methods from listenerType */ + for (int i = 0 ; i < lms.length ; ++i) + { + newClass = ByteUtility.addBytes(newClass,(short)1); // access_flags (fixed) + newClass = ByteUtility.addBytes(newClass,(short)(cpBaseIndex+3*i+0)); // name_index (variable) + newClass = ByteUtility.addBytes(newClass,(short)(cpBaseIndex+3*i+1)); // descriptor_index (variable) + newClass = ByteUtility.addBytes(newClass,(short)1); // attribute_count (fixed) + newClass = ByteUtility.addBytes(newClass,(short)3); // attribute_name_index code(fixed) + + // Code Attribute Length + int length = 32; + if( 0 < excpIndex[i].length ) + { length += 5 + 8 * ( 1 + excpIndex[i].length ); } + if(propertyChangeFlag[i]) + { length += 2; } + newClass = ByteUtility.addBytes(newClass,(long)length); // attribute_length (variable) + + // start code attribute + newClass = ByteUtility.addBytes(newClass,(short)6); // max_stack (fixed) + newClass = ByteUtility.addBytes(newClass,(short)3); // max_locals (fixed) + + // Code Length + length = 20; + if(exceptionable && 0 < excpIndex[i].length) + { length += 5; } + if(propertyChangeFlag[i]) + { length += 2; } + newClass = ByteUtility.addBytes(newClass,(long)length); // code_length (variable) + + // start code + newClass = ByteUtility.addBytes(newClass,(byte)0x2A); // aload_0 (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0xB4); // getfield (fixed) + newClass = ByteUtility.addBytes(newClass,(short)15); // index (fixed) + + + if(propertyChangeFlag[i]) + { // the propertyName is passed as the first parameter + newClass = ByteUtility.addBytes(newClass,(byte)0x2B); // aload_1 (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0xB6); // invokevirtual (fixed) + newClass = ByteUtility.addBytes(newClass,(short)cpIndexPCE); // methodref (variable) + } + else + { // the eventMethodName is passed as the first parameter + // Target for method invocation. + newClass = ByteUtility.addBytes(newClass,(byte)0x12); // ldc (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)(cpBaseIndex+3*i+2)); // index (byte) (variable) + } + + newClass = ByteUtility.addBytes(newClass,(byte)0x04); // iconst_1 (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0xBD); // anewarray (fixed) + newClass = ByteUtility.addBytes(newClass,(short)10); // Class java/lang/Object (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0x59); // dup (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0x03); // iconst_0 (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0x2B); // aload_1 (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0x53); // aastore (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0xB9); // invokeinterface (fixed) + + // index to processEvent or processExceptionableEvent method + length = 23; // actually an index into cp + if(exceptionable && nonExceptionable) + { // interface method index + if( 0 < lms[i].getExceptionTypes().length ) + { length += 5; } + } + else if(exceptionable) + { length += 2; } + newClass = ByteUtility.addBytes(newClass,(short)length); // index (process??????...) (variable) + + newClass = ByteUtility.addBytes(newClass,(byte)0x03); // iconst_0 (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0x00); // noop (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0xB1); // return (fixed) + + if(exceptionable && 0 < excpIndex[i].length) + { // exception code + newClass = ByteUtility.addBytes(newClass,(byte)0x4D); // astore_2 (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0x2C); // aload_2 (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0xBF); // athrow (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0x57); // pop (fixed) + newClass = ByteUtility.addBytes(newClass,(byte)0xB1); // return (fixed) + // end code + + // exception table + length = excpIndex[i].length; + newClass = ByteUtility.addBytes(newClass,(short)(1+length)); // exception_table_length (variable) + for( int j = 0 ; j < length ; j++ ) + { // catch exception types and rethrow + newClass = ByteUtility.addBytes(newClass,(short)0); // start_pc (fixed) + if(propertyChangeFlag[i]) + { + newClass = ByteUtility.addBytes(newClass,(short)21); // end_pc (fixed) + newClass = ByteUtility.addBytes(newClass,(short)22); // handler_pc (fixed) + } + else + { + newClass = ByteUtility.addBytes(newClass,(short)19); // end_pc (fixed) + newClass = ByteUtility.addBytes(newClass,(short)20); // handler_pc (fixed) + } + newClass = ByteUtility.addBytes(newClass,(short)excpIndex[i][j]); // catch_type (variable) + } + // catch "exception" and trap it + newClass = ByteUtility.addBytes(newClass,(short)0); // start_pc (fixed) + if(propertyChangeFlag[i]) + { + newClass = ByteUtility.addBytes(newClass,(short)21); // end_pc (fixed) + newClass = ByteUtility.addBytes(newClass,(short)25); // handler_pc (fixed) + } + else + { + newClass = ByteUtility.addBytes(newClass,(short)19); // end_pc (fixed) + newClass = ByteUtility.addBytes(newClass,(short)23); // handler_pc (fixed) + } + if(nonExceptionable) + { newClass = ByteUtility.addBytes(newClass,(short)26); } // catch_type (fixed) + else // or + { newClass = ByteUtility.addBytes(newClass,(short)23); } // catch_type (fixed) + } + else + { newClass = ByteUtility.addBytes(newClass,(short)0); } // exception_table_length (fixed) + // attributes on the code attribute (none) + newClass = ByteUtility.addBytes(newClass,(short)0); // attribute_count (fixed) + // end code attribute + + + }/* End for*/ + // Class Attributes (none for this) + newClass = ByteUtility.addBytes(newClass,(short)0); // attribute_count (fixed) + /* done */ + + logger.debug("adapterName: " + finalAdapterClassName); + logger.debug("cpCount: " + count + " = " + BASECPCOUNT + " + " + cpCount); + logger.debug("methodCount: " + (lms.length+1)); + // output to disk class file + /* ****************************************************************************************** */ + + // now create the class and load it + // return the Class. + + if (writeClassFile) + { + try + { + // removed "WRITEDIRECTORY+", as this path is already part of 'finalAdapterClassName' + FileOutputStream fos = new FileOutputStream(finalAdapterClassName+".class"); + fos.write(newClass); + fos.close(); + } + catch(IOException ex) + { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + } + + try + { + Class ret = ldr.loadClass(finalAdapterClassName); + logger.debug("EventAdapterGenerator: " + + ret.getName() + + " dynamically generated"); + return ret; + } + catch (ClassNotFoundException ex) + { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + } + } + + try + { + Class ret = ldr.defineClass(finalAdapterClassName,newClass); + logger.debug("EventAdapterGenerator: " + + ret.getName() + + " dynamically generated"); + return ret; + } + catch(Exception ex) + { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + } + } + return null; + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertor.java b/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertor.java new file mode 100644 index 000000000..9ded872a1 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertor.java @@ -0,0 +1,31 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.type; + +/** + * A TypeConvertor is used to convert an object of one type to + * one of another type. The convertor is invoked with the class of the + * from object, the desired class, and the from object itself. The + * convertor must return a new object of the desired class. + * + * @author Sanjiva Weerawarana + * @see TypeConvertorRegistry + */ +public interface TypeConvertor { + public Object convert (Class from, Class to, Object obj); + public String getCodeGenString (); +} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertorRegistry.java b/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertorRegistry.java new file mode 100644 index 000000000..693e464ee --- /dev/null +++ b/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertorRegistry.java @@ -0,0 +1,206 @@ +/* + * Copyright 2004,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.volmit.iris.util.bsf.util.type; + +import java.awt.Color; +import java.awt.Font; +import java.util.Hashtable; + +/** + * The TypeConvertorRegistry is the registry of type convertors. + * It has lookup and register capabilities based on the types to be + * converted as well as by some object key. + * + * @author Sanjiva Weerawarana + * @author Matthew J. Duftler + * @see TypeConvertorRegistry + */ +public class TypeConvertorRegistry { + Hashtable reg = new Hashtable (); + Hashtable keyedReg = new Hashtable (); + + // register some standard convertors at construction time + public TypeConvertorRegistry () { + // no-op convertors: cvt from primitive wrappers to the object wrapper + TypeConvertor tc = new TypeConvertor () { + public Object convert (Class from, Class to, Object obj) { + return obj; + } + + public String getCodeGenString() { + return "(Class from, Class to, Object obj) {\n" + + "return obj;\n" + + "}"; + } + }; + register (Boolean.class, boolean.class, tc); + register (boolean.class, Boolean.class, tc); + register (Byte.class, byte.class, tc); + register (byte.class, Byte.class, tc); + register (Character.class, char.class, tc); + register (char.class, Character.class, tc); + register (Short.class, short.class, tc); + register (short.class, Short.class, tc); + register (Integer.class, int.class, tc); + register (int.class, Integer.class, tc); + register (Long.class, long.class, tc); + register (long.class, Long.class, tc); + register (Float.class, float.class, tc); + register (float.class, Float.class, tc); + register (Double.class, double.class, tc); + register (double.class, Double.class, tc); + + // object to string: the registry special cases this one as the backup + // if the target is string and there is no special convertor available + // otherwise + tc = new TypeConvertor () { + public Object convert (Class from, Class to, Object obj) { + return (obj == null) ? "(null)" : obj.toString (); + } + + public String getCodeGenString() { + return "(Class from, Class to, Object obj) {\n" + + "return (obj == null) ? \"(null)\" : obj.toString ();\n" + + "}"; + } + }; + register (Object.class, String.class, tc); + + // convert strings to various primitives (both their object versions + // and wrappers for primitive versions) + tc = new TypeConvertor () { + public Object convert (Class from, Class to, Object obj) { + String str = (String) obj; + if (to == Boolean.class || to == boolean.class) { + return Boolean.valueOf (str); + } else if (to == Byte.class || to == byte.class) { + return Byte.valueOf (str); + } else if (to == Character.class || to == char.class) { + return new Character (str.charAt (0)); + } else if (to == Short.class || to == short.class) { + return Short.valueOf (str); + } else if (to == Integer.class || to == int.class) { + return Integer.valueOf (str); + } else if (to == Long.class || to == long.class) { + return Long.valueOf (str); + } else if (to == Float.class || to == float.class) { + return Float.valueOf (str); + } else if (to == Double.class || to == double.class) { + return Double.valueOf (str); + } else { + return null; + } + } + + public String getCodeGenString() { + return "(Class from, Class to, Object obj) {\n" + + "String str = (String) obj;\n" + + "if (to == Boolean.class || to == boolean.class) {\n" + + "return Boolean.valueOf (str);\n" + + "} else if (to == Byte.class || to == byte.class) {\n" + + "return Byte.valueOf (str);\n" + + "} else if (to == Character.class || to == char.class) {\n" + + "return new Character (str.charAt (0));\n" + + "} else if (to == Short.class || to == short.class) {\n" + + "return Short.valueOf (str);\n" + + "} else if (to == Integer.class || to == int.class) {\n" + + "return Integer.valueOf (str);\n" + + "} else if (to == Long.class || to == long.class) {\n" + + "return Long.valueOf (str);\n" + + "} else if (to == Float.class || to == float.class) {\n" + + "return Float.valueOf (str);\n" + + "} else if (to == Double.class || to == double.class) {\n" + + "return Double.valueOf (str);\n" + + "} else {\n" + + "return null;\n" + + "}\n" + + "}"; + } + }; + register (String.class, boolean.class, tc); + register (String.class, Boolean.class, tc); + register (String.class, byte.class, tc); + register (String.class, Byte.class, tc); + register (String.class, char.class, tc); + register (String.class, Character.class, tc); + register (String.class, short.class, tc); + register (String.class, Short.class, tc); + register (String.class, int.class, tc); + register (String.class, Integer.class, tc); + register (String.class, long.class, tc); + register (String.class, Long.class, tc); + register (String.class, float.class, tc); + register (String.class, Float.class, tc); + register (String.class, double.class, tc); + register (String.class, Double.class, tc); + + // strings to fonts + tc = new TypeConvertor () { + public Object convert (Class from, Class to, Object obj) { + return Font.decode ((String) obj); + } + + public String getCodeGenString() { + return "(Class from, Class to, Object obj) {\n" + + "return Font.decode ((String) obj);\n" + + "}"; + } + }; + register (String.class, Font.class, tc); + + // strings to colors + tc = new TypeConvertor () { + public Object convert (Class from, Class to, Object obj) { + return Color.decode ((String) obj); + } + + public String getCodeGenString() { + return "(Class from, Class to, Object obj) {\n" + + "return Color.decode ((String) obj);\n" + + "}"; + } + }; + register (String.class, Color.class, tc); + } + // lookup a convertor + public TypeConvertor lookup (Class from, Class to) { + String key = from.getName () + " -> " + to.getName (); + TypeConvertor tc = (TypeConvertor) reg.get (key); + if (tc == null) { + if (from != void.class + && from != Void.class + && to == String.class) { + // find the object -> string convertor + return lookup (Object.class, String.class); + } + } + return tc; + } + // lookup a convertor by key + public TypeConvertor lookupByKey (Object key) { + return (TypeConvertor) keyedReg.get (key); + } + // register a convertor + public void register (Class from, Class to, TypeConvertor convertor) { + String key = from.getName () + " -> " + to.getName (); + reg.put (key, convertor); + } + // register a convertor by key + public void registerByKey (Object key, TypeConvertor convertor) { + keyedReg.put (key, convertor); + } +} From 897669a0699abe2aa26ac00909c8af0ca7562108 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sat, 7 Aug 2021 22:42:17 -0400 Subject: [PATCH 18/28] Fix parallax closer --- .../volmit/iris/engine/framework/EngineCompositeGenerator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java index f3cb1ab41..d41bb377b 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java @@ -731,6 +731,8 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce ticker.interrupt(); } + cleaner.interrupt(); + if (getComposite() != null) { getComposite().close(); From 8e032fa26a4a62d42f5b0fdb1de159624b3c58ca Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sat, 7 Aug 2021 23:11:09 -0400 Subject: [PATCH 19/28] Scripting engine --- build.gradle | 4 +- .../command/studio/CommandIrisStudio.java | 3 + .../studio/CommandIrisStudioExecute.java | 77 ++ .../iris/core/project/loader/IrisData.java | 13 +- .../project/loader/ScriptResourceLoader.java | 160 +++ .../com/volmit/iris/engine/IrisEngine.java | 7 + .../iris/engine/IrisExecutionEnvironment.java | 56 +- .../volmit/iris/engine/framework/Engine.java | 3 + .../object/common/IrisScript.java} | 52 +- .../scripting/EngineExecutionEnvironment.java | 11 + .../engine/scripting/IrisScriptingAPI.java | 104 ++ .../com/volmit/iris/util/bsf/BSFEngine.java | 253 ----- .../volmit/iris/util/bsf/BSFException.java | 71 -- .../com/volmit/iris/util/bsf/BSFManager.java | 913 ------------------ .../volmit/iris/util/bsf/Languages.properties | 50 - .../java/com/volmit/iris/util/bsf/Main.java | 190 ---- .../util/bsf/engines/jacl/BSFCommand.java | 107 -- .../util/bsf/engines/jacl/JaclEngine.java | 136 --- .../util/bsf/engines/java/JavaEngine.java | 352 ------- .../engines/javaclass/JavaClassEngine.java | 73 -- .../engines/javascript/JavaScriptEngine.java | 233 ----- .../util/bsf/engines/jython/JythonEngine.java | 244 ----- .../bsf/engines/netrexx/NetRexxEngine.java | 497 ---------- .../util/bsf/engines/xslt/XSLTEngine.java | 193 ---- .../util/bsf/engines/xslt/XSLTResultNode.java | 33 - .../iris/util/bsf/util/BSFClassLoader.java | 74 -- .../iris/util/bsf/util/BSFEngineImpl.java | 203 ---- .../iris/util/bsf/util/BSFEventProcessor.java | 92 -- .../BSFEventProcessorReturningEventInfos.java | 164 ---- .../iris/util/bsf/util/BSFFunctions.java | 54 -- .../com/volmit/iris/util/bsf/util/Bean.java | 38 - .../volmit/iris/util/bsf/util/CodeBuffer.java | 479 --------- .../iris/util/bsf/util/EngineUtils.java | 379 -------- .../volmit/iris/util/bsf/util/IOUtils.java | 51 - .../iris/util/bsf/util/IndentWriter.java | 85 -- .../com/volmit/iris/util/bsf/util/JNIUtils.c | 228 ----- .../com/volmit/iris/util/bsf/util/JNIUtils.h | 62 -- .../volmit/iris/util/bsf/util/JavaUtils.java | 55 -- .../iris/util/bsf/util/MethodUtils.java | 517 ---------- .../volmit/iris/util/bsf/util/ObjInfo.java | 88 -- .../iris/util/bsf/util/ObjectRegistry.java | 63 -- .../iris/util/bsf/util/ReflectionUtils.java | 421 -------- .../iris/util/bsf/util/ScriptSymbolTable.java | 44 - .../iris/util/bsf/util/StringUtils.java | 412 -------- .../iris/util/bsf/util/cf/CFDriver.java | 196 ---- .../iris/util/bsf/util/cf/CodeFormatter.java | 372 ------- .../util/bsf/util/event/EventAdapter.java | 35 - .../util/bsf/util/event/EventAdapterImpl.java | 35 - .../bsf/util/event/EventAdapterRegistry.java | 103 -- .../util/bsf/util/event/EventProcessor.java | 35 - .../java_awt_event_ActionAdapter.java | 30 - .../java_awt_event_AdjustmentAdapter.java | 30 - .../java_awt_event_ComponentAdapter.java | 39 - .../java_awt_event_ContainerAdapter.java | 33 - .../adapters/java_awt_event_FocusAdapter.java | 33 - .../adapters/java_awt_event_ItemAdapter.java | 30 - .../adapters/java_awt_event_KeyAdapter.java | 36 - .../adapters/java_awt_event_MouseAdapter.java | 42 - .../java_awt_event_MouseMotionAdapter.java | 33 - .../adapters/java_awt_event_TextAdapter.java | 30 - .../java_awt_event_WindowAdapter.java | 48 - .../java_beans_PropertyChangeAdapter.java | 30 - .../java_beans_VetoableChangeAdapter.java | 41 - .../event/generator/AdapterClassLoader.java | 102 -- .../bsf/util/event/generator/ByteUtility.java | 331 ------- .../bsf/util/event/generator/Bytecode.java | 105 -- .../generator/EventAdapterGenerator.java | 568 ----------- .../util/bsf/util/type/TypeConvertor.java | 31 - .../bsf/util/type/TypeConvertorRegistry.java | 206 ---- src/main/resources/plugin.yml | 2 + 70 files changed, 470 insertions(+), 9450 deletions(-) create mode 100644 src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java create mode 100644 src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java rename src/main/java/com/volmit/iris/{util/bsf/BSFDeclaredBean.java => engine/object/common/IrisScript.java} (53%) create mode 100644 src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/BSFEngine.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/BSFException.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/BSFManager.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/Languages.properties delete mode 100644 src/main/java/com/volmit/iris/util/bsf/Main.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/jacl/BSFCommand.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/jacl/JaclEngine.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/java/JavaEngine.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/javaclass/JavaClassEngine.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/javascript/JavaScriptEngine.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/jython/JythonEngine.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/netrexx/NetRexxEngine.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTEngine.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTResultNode.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/BSFClassLoader.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/BSFEngineImpl.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessor.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessorReturningEventInfos.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/BSFFunctions.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/Bean.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/CodeBuffer.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/EngineUtils.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/IOUtils.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/IndentWriter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.c delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.h delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/JavaUtils.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/MethodUtils.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/ObjInfo.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/ObjectRegistry.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/ReflectionUtils.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/ScriptSymbolTable.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/StringUtils.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/cf/CFDriver.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/cf/CodeFormatter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterImpl.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterRegistry.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/EventProcessor.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ActionAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_AdjustmentAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ComponentAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ContainerAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_FocusAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ItemAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_KeyAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseMotionAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_TextAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_WindowAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_PropertyChangeAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_VetoableChangeAdapter.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/generator/AdapterClassLoader.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/generator/ByteUtility.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/generator/Bytecode.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/event/generator/EventAdapterGenerator.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertor.java delete mode 100644 src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertorRegistry.java diff --git a/build.gradle b/build.gradle index b421f0183..69a910474 100644 --- a/build.gradle +++ b/build.gradle @@ -145,6 +145,6 @@ dependencies { implementation 'com.google.code.gson:gson:2.8.7' implementation 'org.ow2.asm:asm:9.2' implementation 'com.google.guava:guava:30.1.1-jre' - - + implementation 'bsf:bsf:2.4.0' + implementation 'rhino:js:1.7R2' } \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java index 198c5cae6..993cdf13f 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java @@ -29,6 +29,9 @@ public class CommandIrisStudio extends MortarCommand { @Command private CommandIrisStudioCreate create; + @Command + private CommandIrisStudioExecute execute; + @Command private CommandIrisStudioOpen open; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java new file mode 100644 index 000000000..a63017d48 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java @@ -0,0 +1,77 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.command.studio; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.core.tools.IrisWorlds; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.IrisAccess; +import com.volmit.iris.engine.object.common.IrisScript; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; + +public class CommandIrisStudioExecute extends MortarCommand { + public CommandIrisStudioExecute() { + super("execute", "ex"); + requiresPermission(Iris.perm.studio); + setDescription("Execute a script"); + setCategory("Studio"); + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + if ((args.length == 0 || args.length == 1) && sender.isPlayer() && IrisWorlds.isIrisWorld(sender.player().getWorld())) { + IrisData data = IrisWorlds.access(sender.player().getWorld()).getData(); + if (data == null) { + sender.sendMessage("Tab complete options only work for summons while in an Iris world."); + } else if (args.length == 0) { + list.add(data.getScriptLoader().getPossibleKeys()); + } else if (args.length == 1) { + list.add(data.getScriptLoader().getPossibleKeys(args[0])); + } + } + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + if (!IrisSettings.get().isStudio()) { + sender.sendMessage("To use Iris Studio, please enable studio in Iris/settings.json"); + return true; + } + + IrisAccess a = IrisToolbelt.access(sender.player().getWorld()); + + if(a != null) + { + ((Engine)a.getEngineAccess(0)).getExecution().execute(args[0]); + Iris.info("Executed. See script output in console."); + } + + return true; + } + + @Override + protected String getArgsUsage() { + return ""; + } +} diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java index ce9bc6743..503571c37 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java +++ b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java @@ -22,6 +22,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.block.IrisBlockData; +import com.volmit.iris.engine.object.common.IrisScript; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.object.entity.IrisEntity; import com.volmit.iris.engine.object.jigsaw.IrisJigsawPiece; @@ -58,6 +59,7 @@ public class IrisData { private ResourceLoader blockLoader; private ResourceLoader expressionLoader; private ResourceLoader objectLoader; + private ResourceLoader scriptLoader; private KMap, ResourceLoader> loaders = new KMap<>(); private boolean closed; private final File dataFolder; @@ -96,7 +98,11 @@ public class IrisData { ResourceLoader r = null; if (registrant.equals(IrisObject.class)) { r = (ResourceLoader) new ObjectResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName()); - } else { + } + else if (registrant.equals(IrisScript.class)) { + r = (ResourceLoader) new ScriptResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName()); + } + else { r = new ResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName(), registrant); } @@ -133,6 +139,7 @@ public class IrisData { this.blockLoader = registerLoader(IrisBlockData.class); this.expressionLoader = registerLoader(IrisExpression.class); this.objectLoader = registerLoader(IrisObject.class); + this.scriptLoader = registerLoader(IrisScript.class); } public void dump() { @@ -195,6 +202,10 @@ public class IrisData { return loadAny(key, (dm) -> dm.getSpawnerLoader().load(key, false)); } + public static IrisScript loadAnyScript(String key) { + return loadAny(key, (dm) -> dm.getScriptLoader().load(key, false)); + } + public static IrisRegion loadAnyRegion(String key) { return loadAny(key, (dm) -> dm.getRegionLoader().load(key, false)); } diff --git a/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java b/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java new file mode 100644 index 000000000..50d7bdd6b --- /dev/null +++ b/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java @@ -0,0 +1,160 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.project.loader; + +import com.volmit.iris.Iris; +import com.volmit.iris.engine.object.common.IrisScript; +import com.volmit.iris.engine.object.objects.IrisObject; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.format.C; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.io.IO; +import com.volmit.iris.util.math.M; +import com.volmit.iris.util.scheduling.ChronoLatch; +import com.volmit.iris.util.scheduling.J; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; + +import java.io.File; +import java.util.concurrent.atomic.AtomicInteger; + +public class ScriptResourceLoader extends ResourceLoader { + + public ScriptResourceLoader(File root, IrisData idm, String folderName, String resourceTypeName) { + super(root, idm, folderName, resourceTypeName, IrisScript.class); + } + + public boolean supportsSchemas() { + return false; + } + + public int getSize() { + return loadCache.size(); + } + + public IrisScript loadFile(File j, String key, String name) { + lock.lock(); + try { + PrecisionStopwatch p = PrecisionStopwatch.start(); + IrisScript t = new IrisScript(IO.readAll(j)); + loadCache.put(key, t); + t.setLoadKey(name); + t.setLoader(manager); + t.setLoadFile(j); + logLoad(j, t); + lock.unlock(); + tlt.addAndGet(p.getMilliseconds()); + return t; + } catch (Throwable e) { + Iris.reportError(e); + lock.unlock(); + Iris.warn("Couldn't read " + resourceTypeName + " file: " + j.getPath() + ": " + e.getMessage()); + return null; + } + } + + public String[] getPossibleKeys() { + if (possibleKeys != null) { + return possibleKeys; + } + + Iris.debug("Building " + resourceTypeName + " Possibility Lists"); + KSet m = new KSet<>(); + + for (File i : getFolders()) { + for (File j : i.listFiles()) { + if (j.isFile() && j.getName().endsWith(".js")) { + m.add(j.getName().replaceAll("\\Q.iob\\E", "")); + } else if (j.isDirectory()) { + for (File k : j.listFiles()) { + if (k.isFile() && k.getName().endsWith(".js")) { + m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.iob\\E", "")); + } else if (k.isDirectory()) { + for (File l : k.listFiles()) { + if (l.isFile() && l.getName().endsWith(".js")) { + m.add(j.getName() + "/" + k.getName() + "/" + l.getName().replaceAll("\\Q.iob\\E", "")); + } + } + } + } + } + } + } + + KList v = new KList<>(m); + possibleKeys = v.toArray(new String[0]); + return possibleKeys; + } + + public File findFile(String name) { + lock.lock(); + for (File i : getFolders(name)) { + for (File j : i.listFiles()) { + if (j.isFile() && j.getName().endsWith(".js") && j.getName().split("\\Q.\\E")[0].equals(name)) { + lock.unlock(); + return j; + } + } + + File file = new File(i, name + ".js"); + + if (file.exists()) { + lock.unlock(); + return file; + } + } + + Iris.warn("Couldn't find " + resourceTypeName + ": " + name); + + lock.unlock(); + return null; + } + + public IrisScript load(String name, boolean warn) { + String key = name + "-" + objectClass.getCanonicalName(); + + if (loadCache.containsKey(key)) { + IrisScript t = loadCache.get(key); + return t; + } + + lock.lock(); + for (File i : getFolders(name)) { + for (File j : i.listFiles()) { + if (j.isFile() && j.getName().endsWith(".js") && j.getName().split("\\Q.\\E")[0].equals(name)) { + lock.unlock(); + return loadFile(j, key, name); + } + } + + File file = new File(i, name + ".js"); + + if (file.exists()) { + lock.unlock(); + return loadFile(file, key, name); + } + } + + Iris.warn("Couldn't find " + resourceTypeName + ": " + name); + + lock.unlock(); + return null; + } +} diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index 6be28e39f..c488a5a3c 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -28,6 +28,7 @@ import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer; import com.volmit.iris.engine.object.decoration.IrisDecorator; import com.volmit.iris.engine.object.engine.IrisEngineData; import com.volmit.iris.engine.object.objects.IrisObjectPlacement; +import com.volmit.iris.engine.scripting.EngineExecutionEnvironment; import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates; @@ -64,6 +65,9 @@ public class IrisEngine extends BlockPopulator implements Engine { @Getter private final EngineEffects effects; + @Getter + private final EngineExecutionEnvironment execution; + @Getter private final EngineWorldManager worldManager; @@ -116,10 +120,13 @@ public class IrisEngine extends BlockPopulator implements Engine { Iris.callEvent(new IrisEngineHotloadEvent(this)); context = new IrisContext(this); context.touch(); + execution = new IrisExecutionEnvironment(this); } @Override public IrisEngineData getEngineData() { + World w = null; + return engineData.aquire(() -> { File f = new File(getWorld().worldFolder(), "iris/engine-data/" + getDimension().getLoadKey() + "-" + getIndex() + ".json"); diff --git a/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java index e8896350d..063eb5904 100644 --- a/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java +++ b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java @@ -18,16 +18,70 @@ package com.volmit.iris.engine; +import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.scripting.EngineExecutionEnvironment; +import com.volmit.iris.engine.scripting.IrisScriptingAPI; import lombok.Data; +import org.apache.bsf.BSFEngine; +import org.apache.bsf.BSFException; +import org.apache.bsf.BSFManager; +import org.apache.bsf.engines.javascript.JavaScriptEngine; @Data public class IrisExecutionEnvironment implements EngineExecutionEnvironment { + private final BSFManager manager; private final Engine engine; + private final IrisScriptingAPI api; + private JavaScriptEngine javaScriptEngine; - IrisExecutionEnvironment(Engine engine) + public IrisExecutionEnvironment(Engine engine) { this.engine = engine; + this.api = new IrisScriptingAPI(engine); + this.manager = new BSFManager(); + this.manager.setClassLoader(Iris.class.getClassLoader()); + try { + this.manager.declareBean("Iris", api, api.getClass()); + this.javaScriptEngine = (JavaScriptEngine) this.manager.loadScriptingEngine("javascript"); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + public void execute(String script) + { + try { + javaScriptEngine.exec("", 0, 0, getEngine().getData().getScriptLoader().load(script)); + } catch (BSFException e) { + e.printStackTrace(); + } + } + + public Object evaluate(String script) + { + try { + return javaScriptEngine.eval("", 0, 0, getEngine().getData().getScriptLoader().load(script)); + } catch (BSFException e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void execute(String script, double x, double y, double z) { + api.setX(x); + api.setY(y); + api.setZ(z); + execute(script); + } + + @Override + public Object evaluate(String script, double x, double y, double z) { + api.setX(x); + api.setY(y); + api.setZ(z); + return evaluate(script); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index 6a5d7b2d2..d8c80ce7b 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -34,6 +34,7 @@ import com.volmit.iris.engine.object.loot.IrisLootTable; import com.volmit.iris.engine.object.meta.InventorySlotType; import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.engine.parallax.ParallaxAccess; +import com.volmit.iris.engine.scripting.EngineExecutionEnvironment; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.data.B; @@ -65,6 +66,8 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro IrisContext getContext(); + EngineExecutionEnvironment getExecution(); + double getMaxBiomeObjectDensity(); double getMaxBiomeDecoratorDensity(); diff --git a/src/main/java/com/volmit/iris/util/bsf/BSFDeclaredBean.java b/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java similarity index 53% rename from src/main/java/com/volmit/iris/util/bsf/BSFDeclaredBean.java rename to src/main/java/com/volmit/iris/engine/object/common/IrisScript.java index f68a98435..e5a1c21de 100644 --- a/src/main/java/com/volmit/iris/util/bsf/BSFDeclaredBean.java +++ b/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java @@ -16,24 +16,40 @@ * along with this program. If not, see . */ -package com.volmit.iris.util.bsf; +package com.volmit.iris.engine.object.common; -/** - * BSFDeclaredBeans are used internally by BSF to encapsulate information being - * passed between a BSFManager and its various BSFEngines. Note that the - * constructor is not public because this is not a public class. - * - * @author Matthew J. Duftler - * @author Sanjiva Weerawarana - */ -public class BSFDeclaredBean { - public String name; - public Object bean; - public Class type; +import com.volmit.iris.core.project.loader.IrisRegistrant; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.bukkit.Bukkit; - BSFDeclaredBean(String name, Object bean, Class type) { - this.name = name; - this.bean = bean; - this.type = type; - } +@EqualsAndHashCode(callSuper = true) +@Data +public class IrisScript extends IrisRegistrant { + private final String source; + + public IrisScript() + { + this(""); + } + + public IrisScript(String source) + { + this.source = source; + } + + @Override + public String getFolderName() { + return "scripts"; + } + + @Override + public String getTypeName() { + return "Script"; + } + + public String toString() + { + return source; + } } diff --git a/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java b/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java index 91538ff60..a2ebd613a 100644 --- a/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java +++ b/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java @@ -19,11 +19,22 @@ package com.volmit.iris.engine.scripting; import com.volmit.iris.engine.framework.Engine; +import org.apache.bsf.BSFManager; public interface EngineExecutionEnvironment { Engine getEngine(); + BSFManager getManager(); + + void execute(String script); + + Object evaluate(String script); + + void execute(String script, double x, double y, double z); + + Object evaluate(String script, double x, double y, double z); + default void close() { diff --git a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java new file mode 100644 index 000000000..835923c26 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java @@ -0,0 +1,104 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.scripting; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.engine.IrisComplex; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.EngineFramework; +import com.volmit.iris.engine.object.biome.IrisBiome; +import com.volmit.iris.engine.object.dimensional.IrisDimension; +import com.volmit.iris.engine.object.noise.IrisExpression; +import lombok.Data; + +@Data +public class IrisScriptingAPI { + private final Engine engine; + private double x = 0; + private double y = 0; + private double z = 0; + + public IrisScriptingAPI(Engine engine) + { + this.engine = engine; + } + + public IrisData getData() + { + return getEngine().getData(); + } + + public EngineFramework getFramework() + { + return getEngine().getFramework(); + } + + public IrisComplex getComplex() + { + return getFramework().getComplex(); + } + + public long getSeed() + { + return getEngine().getTarget().getWorld().seed(); + } + + public double expression(String expressionName, double x, double y, double z) + { + IrisExpression expression = getData().getExpressionLoader().load(expressionName); + return expression.evaluate(getComplex().getRng(), x, y, z); + } + + public double expression(String expressionName, double x, double z) + { + IrisExpression expression = getData().getExpressionLoader().load(expressionName); + return expression.evaluate(getComplex().getRng(), x, z); + } + + public IrisBiome getBiomeAt(int x, int z) + { + return getEngine().getSurfaceBiome(x, z); + } + + public IrisDimension getDimension() + { + return getEngine().getDimension(); + } + + public void info(String log) + { + Iris.info(log); + } + + public void debug(String log) + { + Iris.debug(log); + } + + public void warn(String log) + { + Iris.warn(log); + } + + public void error(String log) + { + Iris.error(log); + } +} diff --git a/src/main/java/com/volmit/iris/util/bsf/BSFEngine.java b/src/main/java/com/volmit/iris/util/bsf/BSFEngine.java deleted file mode 100644 index 6a3b7247d..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/BSFEngine.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.bsf; - -import java.beans.PropertyChangeListener; -import java.util.Vector; - -import com.volmit.iris.util.bsf.util.CodeBuffer; - -/** - * This is the view of a scripting engine assumed by the Bean Scripting - * Framework. This interface is used when an application decides to - * run some script under application control. (This is the reverse of - * the more common situation, which is that of the scripting language - * calling into the application.) - *

- * When a scripting engine is first fired up, the initialize() - * method is called right after construction. - *

- * A scripting engine must provide two access points for applications - * to call into them: via function calls and via expression evaluation. - * It must also support loading scripts. - *

- * A scripting engine is a property change listener and will be notified - * when any of the relevant properties of the manager change. (See - * BSFManager to see which of its properties are bound.) - * - * @author Sanjiva Weerawarana - * @author Matthew J. Duftler - */ -public interface BSFEngine extends PropertyChangeListener { - - /** - * This is used by an application to invoke an anonymous function. An - * anonymous function is a multi-line script which when evaluated will - * produce a value. These are separated from expressions and scripts - * because the prior are spsed to be good 'ol expressions and scripts - * are not value returning. We allow anonymous functions to have parameters - * as well for completeness. - * - * @param source (context info) the source of this expression - * (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param funcBody the multi-line, value returning script to evaluate - * @param paramNames the names of the parameters above assumes - * @param arguments values of the above parameters - * - * @exception BSFException if anything goes wrong while doin' it. - */ - public Object apply( - String source, - int lineNo, - int columnNo, - Object funcBody, - Vector paramNames, - Vector arguments) - throws BSFException; - /** - * This is used by an application to call into the scripting engine - * to make a function/method call. The "object" argument is the object - * whose method is to be called, if that applies. For non-OO languages, - * this is typically ignored and should be given as null. For pretend-OO - * languages such as VB, this would be the (String) name of the object. - * The arguments are given in the args array. - * - * @param object object on which to make the call - * @param name name of the method / procedure to call - * @param args the arguments to be given to the procedure - * - * @exception BSFException if anything goes wrong while eval'ing a - * BSFException is thrown. The reason indicates the problem. - */ - public Object call(Object object, String name, Object[] args) - throws BSFException; - /** - * This is used by an application to compile an anonymous function. See - * comments in apply for more hdetails. - * - * @param source (context info) the source of this expression - * (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param funcBody the multi-line, value returning script to evaluate - * @param paramNames the names of the parameters above assumes - * @param arguments values of the above parameters - * @param cb the CodeBuffer to compile into - * - * @exception BSFException if anything goes wrong while doin' it. - */ - public void compileApply( - String source, - int lineNo, - int columnNo, - Object funcBody, - Vector paramNames, - Vector arguments, - CodeBuffer cb) - throws BSFException; - /** - * This is used by an application to compile a value-returning expression. - * The expr may be string or some other type, depending on the language. - * The generated code is dumped into the CodeBuffer. - * - * @param source (context info) the source of this expression - * (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param expr the expression to compile - * @param cb the CodeBuffer to compile into - * - * @exception BSFException if anything goes wrong while compiling a - * BSFException is thrown. The reason indicates the problem. - */ - public void compileExpr( - String source, - int lineNo, - int columnNo, - Object expr, - CodeBuffer cb) - throws BSFException; - /** - * This is used by an application to compile some script. The - * script may be string or some other type, depending on the - * language. The generated code is dumped into the CodeBuffer. - * - * @param source (context info) the source of this script - * (e.g., filename) - * @param lineNo (context info) the line number in source for script - * @param columnNo (context info) the column number in source for script - * @param script the script to compile - * @param cb the CodeBuffer to compile into - * - * @exception BSFException if anything goes wrong while compiling a - * BSFException is thrown. The reason indicates the problem. - */ - public void compileScript( - String source, - int lineNo, - int columnNo, - Object script, - CodeBuffer cb) - throws BSFException; - /** - * Declare a bean after the engine has been started. Declared beans - * are beans that are named and which the engine must make available - * to the scripts it runs in the most first class way possible. - * - * @param bean the bean to declare - * - * @exception BSFException if the engine cannot do this operation - */ - public void declareBean(BSFDeclaredBean bean) throws BSFException; - /** - * This is used by an application to evaluate an expression. The - * expression may be string or some other type, depending on the - * language. (For example, for BML it'll be an org.w3c.dom.Element - * object.) - * - * @param source (context info) the source of this expression - * (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param expr the expression to evaluate - * - * @exception BSFException if anything goes wrong while eval'ing a - * BSFException is thrown. The reason indicates the problem. - */ - public Object eval(String source, int lineNo, int columnNo, Object expr) - throws BSFException; - /** - * This is used by an application to execute some script. The - * expression may be string or some other type, depending on the - * language. Returns nothing but if something goes wrong it excepts - * (of course). - * - * @param source (context info) the source of this expression - * (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param script the script to execute - * - * @exception BSFException if anything goes wrong while exec'ing a - * BSFException is thrown. The reason indicates the problem. - */ - public void exec(String source, int lineNo, int columnNo, Object script) - throws BSFException; - /** - * This is used by an application to execute some script, as though - * one were interacting with the language in an interactive session. - * The expression may be string or some other type, depending on the - * language. Returns nothing but if something goes wrong it excepts (of - * course). - * - * @param source (context info) the source of this expression - * (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param script the script to execute - * - * @exception BSFException if anything goes wrong while exec'ing a - * BSFException is thrown. The reason indicates the problem. - */ - public void iexec(String source, int lineNo, int columnNo, Object script) - throws BSFException; - - /** - * This method is used to initialize the engine right after construction. - * This method will be called before any calls to eval or call. At this - * time the engine should capture the current values of interesting - * properties from the manager. In the future, any changes to those - * will be mirrored to me by the manager via a property change event. - * - * @param mgr The BSFManager that's hosting this engine. - * @param lang Language string which this engine is handling. - * @param declaredBeans Vector of BSFDeclaredObject containing beans - * that should be declared into the language runtime at init - * time as best as possible. - * - * @exception BSFException if anything goes wrong while init'ing a - * BSFException is thrown. The reason indicates the problem. - */ - public void initialize(BSFManager mgr, String lang, Vector declaredBeans) - throws BSFException; - /** - * Graceful termination - */ - public void terminate(); - /** - * Undeclare a previously declared bean. - * - * @param bean the bean to undeclare - * - * @exception BSFException if the engine cannot do this operation - */ - public void undeclareBean(BSFDeclaredBean bean) throws BSFException; -} diff --git a/src/main/java/com/volmit/iris/util/bsf/BSFException.java b/src/main/java/com/volmit/iris/util/bsf/BSFException.java deleted file mode 100644 index 2ab480d05..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/BSFException.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.bsf; - -/** - * If something goes wrong while doing some scripting stuff, one of these - * is thrown. The integer code indicates what's wrong and the message - * may give more details. The reason one exception with multiple meanings - * (via the code) [instead of multiple exception types] is used is due to - * the interest to keep the run-time size small. - * - * @author Sanjiva Weerawarana - */ -public class BSFException extends Exception { - public static final int REASON_INVALID_ARGUMENT = 0; - public static final int REASON_IO_ERROR = 10; - public static final int REASON_UNKNOWN_LANGUAGE = 20; - public static final int REASON_EXECUTION_ERROR = 100; - public static final int REASON_UNSUPPORTED_FEATURE = 499; - public static final int REASON_OTHER_ERROR = 500; - - int reason; - Throwable targetThrowable; - - public BSFException (int reason, String msg) { - super (msg); - this.reason = reason; - } - public BSFException (int reason, String msg, Throwable t) { - this (reason, msg); - targetThrowable = t; - } - public BSFException (String msg) { - this (REASON_OTHER_ERROR, msg); - } - public int getReason () { - return reason; - } - public Throwable getTargetException () { - return targetThrowable; - } - public void printStackTrace () { - if (targetThrowable != null) { - String msg = getMessage (); - - if (msg != null && !msg.equals (targetThrowable.getMessage ())) { - System.err.print (msg + ": "); - } - - targetThrowable.printStackTrace (); - } else { - super.printStackTrace (); - } - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/BSFManager.java b/src/main/java/com/volmit/iris/util/bsf/BSFManager.java deleted file mode 100644 index 67179a07a..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/BSFManager.java +++ /dev/null @@ -1,913 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.bsf; - -import java.beans.PropertyChangeSupport; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.MissingResourceException; -import java.util.NoSuchElementException; -import java.util.Properties; -import java.util.StringTokenizer; -import java.util.Vector; - -import com.volmit.iris.util.bsf.util.CodeBuffer; -import com.volmit.iris.util.bsf.util.ObjectRegistry; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This class is the entry point to the bean scripting framework. An - * application wishing to integrate scripting to a Java app would - * place an instance of a BSFManager in their code and use its services - * to register the beans they want to make available for scripting, - * load scripting engines, and run scripts. - *

- * BSFManager serves as the registry of available scripting engines - * as well. Loading and unloading of scripting engines is - * supported as well. Each BSFManager loads one engine per language. - * Several BSFManagers can be created per JVM. - * - * @author Sanjiva Weerawarana - * @author Matthew J. Duftler - * @author Sam Ruby - * @author Olivier Gruber (added original debugging support) - * @author Don Schwarz (added support for registering languages dynamically) - */ -public class BSFManager { - // version string is in the form "abc.yyyymmdd" where - // "abc" represents a dewey decimal number (three levels, each between 0 and 9), - // and "yyyy" a four digit year, "mm" a two digit month, "dd" a two digit day. - // - // Example: "240.20060925" stands for: BSF version "2.4.0" as of "2006-09-25" - protected static String version="240.20061006"; - - // table of registered scripting engines - protected static Hashtable registeredEngines = new Hashtable(); - - // mapping of file extensions to languages - protected static Hashtable extn2Lang = new Hashtable(); - - // table of scripting engine instances created by this manager. - // only one instance of a given language engine is created by a single - // manager instance. - protected Hashtable loadedEngines = new Hashtable(); - - // table of registered beans for use by scripting engines. - protected ObjectRegistry objectRegistry = new ObjectRegistry(); - - // prop change support containing loaded engines to inform when any - // of my interesting properties change - protected PropertyChangeSupport pcs; - - // the class loader to use if a class loader is needed. Default is - // he who loaded me (which may be null in which case its Class.forName). - // protected ClassLoader classLoader = getClass().getClassLoader(); - protected ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // rgf, 2006-01-05 - - // temporary directory to use to dump temporary files into. Note that - // if class files are dropped here then unless this dir is in the - // classpath or unless the classloader knows to look here, the classes - // will not be found. - protected String tempDir = "."; - - // classpath used by those that need a classpath - protected String classPath; - - // stores BSFDeclaredBeans representing objects - // introduced by a client of BSFManager - protected Vector declaredBeans = new Vector(); - - private Log logger = LogFactory.getLog(this.getClass().getName()); - - ////////////////////////////////////////////////////////////////////// - // - // pre-register engines that BSF supports off the shelf - // - ////////////////////////////////////////////////////////////////////// - - static { - try { - Enumeration e = BSFManager.class.getClassLoader().getResources("org/apache/bsf/Languages.properties"); - while (e.hasMoreElements()) { - URL url = (URL)e.nextElement(); - InputStream is = url.openStream(); - - Properties p = new Properties(); - p.load(is); - - for (Enumeration keys = p.propertyNames(); keys.hasMoreElements();) { - - String key = (String) keys.nextElement(); - String value = p.getProperty(key); - String className = value.substring(0, value.indexOf(",")); - - - - - // get the extensions for this language - String exts = value.substring(value.indexOf(",")+1, value.length()); - StringTokenizer st = new StringTokenizer(exts, "|"); - String[] extensions = new String[st.countTokens()]; - for (int i = 0; st.hasMoreTokens(); i++) { - extensions[i] = ((String) st.nextToken()).trim(); - } - - registerScriptingEngine(key, className, extensions); - } - } - } catch (IOException ex) { - - ex.printStackTrace(); - System.err.println("Error reading Languages file " + ex); - } catch (NoSuchElementException nsee) { - - nsee.printStackTrace(); - System.err.println("Syntax error in Languages resource bundle"); - } catch (MissingResourceException mre) { - - mre.printStackTrace(); - System.err.println("Initialization error: " + mre.toString()); - } - } - - public BSFManager() { - pcs = new PropertyChangeSupport(this); - } - - - /** Returns the version string of BSF. - * - * @return version string in the form "abc.yyyymmdd" where - "abc" represents a dewey decimal number (three levels, each between 0 and 9), and - "yyyy" a four digit year, "mm" a two digit month, - "dd" a two digit day. - * -
Example: "240.20061006" - stands for: BSF version 2.4.0 as of 2006-10-06. - * - * - * @since 2006-01-17 - */ - public static String getVersion() { - - return version; - } - - /** - * Apply the given anonymous function of the given language to the given - * parameters and return the resulting value. - * - * @param lang language identifier - * @param source (context info) the source of this expression - (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param funcBody the multi-line, value returning script to evaluate - * @param paramNames the names of the parameters above assumes - * @param arguments values of the above parameters - * - * @exception BSFException if anything goes wrong while running the script - */ - public Object apply(String lang, - String source, - int lineNo, - int columnNo, - Object funcBody, - Vector paramNames, - Vector arguments) - throws BSFException { - logger.debug("BSFManager:apply"); - - final BSFEngine e = loadScriptingEngine(lang); - final String sourcef = source; - final int lineNof = lineNo, columnNof = columnNo; - final Object funcBodyf = funcBody; - final Vector paramNamesf = paramNames; - final Vector argumentsf = arguments; - Object result = null; - - try { - final Object resultf = - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - return e.apply(sourcef, lineNof, columnNof, - funcBodyf, paramNamesf, argumentsf); - } - }); - result = resultf; - } catch (PrivilegedActionException prive) { - - logger.error("Exception: ", prive); - throw (BSFException) prive.getException(); - } - - return result; - } - - /** - * Compile the application of the given anonymous function of the given - * language to the given parameters into the given CodeBuffer. - * - * @param lang language identifier - * @param source (context info) the source of this expression - (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param funcBody the multi-line, value returning script to evaluate - * @param paramNames the names of the parameters above assumes - * @param arguments values of the above parameters - * @param cb code buffer to compile into - * - * @exception BSFException if anything goes wrong while running the script - */ - public void compileApply(String lang, - String source, - int lineNo, - int columnNo, - Object funcBody, - Vector paramNames, - Vector arguments, - CodeBuffer cb) - throws BSFException { - logger.debug("BSFManager:compileApply"); - - final BSFEngine e = loadScriptingEngine(lang); - final String sourcef = source; - final int lineNof = lineNo, columnNof = columnNo; - final Object funcBodyf = funcBody; - final Vector paramNamesf = paramNames; - final Vector argumentsf = arguments; - final CodeBuffer cbf = cb; - - try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - e.compileApply(sourcef, lineNof, columnNof, - funcBodyf, paramNamesf, - argumentsf, cbf); - return null; - } - }); - } catch (PrivilegedActionException prive) { - - logger.error("Exception :", prive); - throw (BSFException) prive.getException(); - } - } - - /** - * Compile the given expression of the given language into the given - * CodeBuffer. - * - * @param lang language identifier - * @param source (context info) the source of this expression - (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param expr the expression to compile - * @param cb code buffer to compile into - * - * @exception BSFException if any error while compiling the expression - */ - public void compileExpr(String lang, - String source, - int lineNo, - int columnNo, - Object expr, - CodeBuffer cb) - throws BSFException { - logger.debug("BSFManager:compileExpr"); - - final BSFEngine e = loadScriptingEngine(lang); - final String sourcef = source; - final int lineNof = lineNo, columnNof = columnNo; - final Object exprf = expr; - final CodeBuffer cbf = cb; - - try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - e.compileExpr(sourcef, lineNof, columnNof, exprf, cbf); - return null; - } - }); - } catch (PrivilegedActionException prive) { - - logger.error("Exception :", prive); - throw (BSFException) prive.getException(); - } - } - - /** - * Compile the given script of the given language into the given - * CodeBuffer. - * - * @param lang language identifier - * @param source (context info) the source of this script - (e.g., filename) - * @param lineNo (context info) the line number in source for script - * @param columnNo (context info) the column number in source for script - * @param script the script to compile - * @param cb code buffer to compile into - * - * @exception BSFException if any error while compiling the script - */ - public void compileScript(String lang, - String source, - int lineNo, - int columnNo, - Object script, - CodeBuffer cb) - throws BSFException { - logger.debug("BSFManager:compileScript"); - - final BSFEngine e = loadScriptingEngine(lang); - final String sourcef = source; - final int lineNof = lineNo, columnNof = columnNo; - final Object scriptf = script; - final CodeBuffer cbf = cb; - - try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - e.compileScript(sourcef, lineNof, columnNof, - scriptf, cbf); - return null; - } - }); - } catch (PrivilegedActionException prive) { - - logger.error("Exception :", prive); - throw (BSFException) prive.getException(); - } - } - - /** - * Declare a bean. The difference between declaring and registering - * is that engines are spsed to make declared beans "pre-available" - * in the scripts as far as possible. That is, if a script author - * needs a registered bean, he needs to look it up in some way. However - * if he needs a declared bean, the language has the responsibility to - * make those beans avaialable "automatically." - *

- * When a bean is declared it is automatically registered as well - * so that any declared bean can be gotton to by looking it up as well. - *

- * If any of the languages that are already running in this manager - * says they don't like this (by throwing an exception) then this - * method will simply quit with that exception. That is, any engines - * that come after than in the engine enumeration will not even be - * told about this new bean. - *

- * So, in general its best to declare beans before the manager has - * been asked to load any engines because then the user can be informed - * when an engine rejects it. Also, its much more likely that an engine - * can declare a bean at start time than it can at any time. - * - * @param beanName name to declare bean as - * @param bean the bean that's being declared - * @param type the type to represent the bean as - * - * @exception BSFException if any of the languages that are already - * running decides to throw an exception when asked to - * declare this bean. - */ - public void declareBean(String beanName, Object bean, Class type) - throws BSFException { - logger.debug("BSFManager:declareBean"); - - registerBean(beanName, bean); - - BSFDeclaredBean tempBean = new BSFDeclaredBean(beanName, bean, type); - declaredBeans.addElement(tempBean); - - Enumeration enginesEnum = loadedEngines.elements(); - BSFEngine engine; - while (enginesEnum.hasMoreElements()) { - engine = (BSFEngine) enginesEnum.nextElement(); - engine.declareBean(tempBean); - } - } - - /** - * Evaluate the given expression of the given language and return the - * resulting value. - * - * @param lang language identifier - * @param source (context info) the source of this expression - (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param expr the expression to evaluate - * - * @exception BSFException if anything goes wrong while running the script - */ - public Object eval(String lang, - String source, - int lineNo, - int columnNo, - Object expr) - throws BSFException { - logger.debug("BSFManager:eval"); - - final BSFEngine e = loadScriptingEngine(lang); - final String sourcef = source; - final int lineNof = lineNo, columnNof = columnNo; - final Object exprf = expr; - Object result = null; - - try { - final Object resultf = - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - return e.eval(sourcef, lineNof, columnNof, exprf); - } - }); - result = resultf; - } catch (PrivilegedActionException prive) { - - logger.error("Exception: ", prive); - throw (BSFException) prive.getException(); - } - - return result; - } - - ////////////////////////////////////////////////////////////////////// - // - // Convenience functions for exec'ing and eval'ing scripts directly - // without loading and dealing with engines etc.. - // - ////////////////////////////////////////////////////////////////////// - - /** - * Execute the given script of the given language. - * - * @param lang language identifier - * @param source (context info) the source of this expression - (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param script the script to execute - * - * @exception BSFException if anything goes wrong while running the script - */ - public void exec(String lang, - String source, - int lineNo, - int columnNo, - Object script) - throws BSFException { - logger.debug("BSFManager:exec"); - - final BSFEngine e = loadScriptingEngine(lang); - final String sourcef = source; - final int lineNof = lineNo, columnNof = columnNo; - final Object scriptf = script; - - try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - e.exec(sourcef, lineNof, columnNof, scriptf); - return null; - } - }); - } catch (PrivilegedActionException prive) { - - logger.error("Exception :", prive); - throw (BSFException) prive.getException(); - } - } - - /** - * Execute the given script of the given language, attempting to - * emulate an interactive session w/ the language. - * - * @param lang language identifier - * @param source (context info) the source of this expression - * (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param script the script to execute - * - * @exception BSFException if anything goes wrong while running the script - */ - public void iexec(String lang, - String source, - int lineNo, - int columnNo, - Object script) - throws BSFException { - logger.debug("BSFManager:iexec"); - - final BSFEngine e = loadScriptingEngine(lang); - final String sourcef = source; - final int lineNof = lineNo, columnNof = columnNo; - final Object scriptf = script; - - try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - e.iexec(sourcef, lineNof, columnNof, scriptf); - return null; - } - }); - } catch (PrivilegedActionException prive) { - - logger.error("Exception :", prive); - throw (BSFException) prive.getException(); - } - } - - /** - * Get classLoader - */ - public ClassLoader getClassLoader() { - logger.debug("BSFManager:getClassLoader"); - return classLoader; - } - - /** - * Get classPath - */ - public String getClassPath() { - logger.debug("BSFManager:getClassPath"); - if (classPath == null) { - try { - classPath = System.getProperty("java.class.path"); - } catch (Throwable t) { - - logger.debug("Exception :", t); - // prolly a security exception .. so no can do - } - } - return classPath; - } - - /** - * Determine the language of a script file by looking at the file - * extension. - * - * @param fileName the name of the file - * - * @return the scripting language the file is in if the file extension - * is known to me (must have been registered via - * registerScriptingEngine). - * - * @exception BSFException if file's extension is unknown. - */ - public static String getLangFromFilename(String fileName) - throws BSFException { - int dotIndex = fileName.lastIndexOf("."); - - if (dotIndex != -1) { - String extn = fileName.substring(dotIndex + 1); - String langval = (String) extn2Lang.get(extn); - String lang = null; - int index, loops = 0; - - if (langval != null) { - while ((index = langval.indexOf(":", 0)) != -1) { - // Great. Multiple language engines registered - // for this extension. - // Try to find first one that is in our classpath. - lang = langval.substring(0, index); - langval = langval.substring(index + 1); - loops++; - - // Test to see if in classpath - try { - String engineName = - (String) registeredEngines.get(lang); - Class.forName(engineName); - } catch (ClassNotFoundException cnfe) { - - // Bummer. - lang = langval; - continue; - } - - // Got past that? Good. - break; - } - if (loops == 0) { lang = langval; } - } - - if (lang != null && lang != "") { - return lang; - } - } - throw new BSFException(BSFException.REASON_OTHER_ERROR, - "file extension missing or unknown: " - + "unable to determine language for '" - + fileName - + "'"); - } - - /** - * Return the current object registry of the manager. - * - * @return the current registry. - */ - public ObjectRegistry getObjectRegistry() { - return objectRegistry; - } - - /** - * Get tempDir - */ - public String getTempDir() { - return tempDir; - } - - /** - * Determine whether a language is registered. - * - * @param lang string identifying a language - * - * @return true iff it is - */ - public static boolean isLanguageRegistered(String lang) { - return (registeredEngines.get(lang) != null); - } - - ////////////////////////////////////////////////////////////////////// - // - // Bean scripting framework services - // - ////////////////////////////////////////////////////////////////////// - - /** - * Load a scripting engine based on the lang string identifying it. - * - * @param lang string identifying language - * @exception BSFException if the language is unknown (i.e., if it - * has not been registered) with a reason of - * REASON_UNKNOWN_LANGUAGE. If the language is known but - * if the interface can't be created for some reason, then - * the reason is set to REASON_OTHER_ERROR and the actual - * exception is passed on as well. - */ - public BSFEngine loadScriptingEngine(String lang) throws BSFException { - logger.debug("BSFManager:loadScriptingEngine"); - - // if its already loaded return that - BSFEngine eng = (BSFEngine) loadedEngines.get(lang); - if (eng != null) { - return eng; - } - - // is it a registered language? - String engineClassName = (String) registeredEngines.get(lang); - if (engineClassName == null) { - logger.error("unsupported language: " + lang); - throw new BSFException(BSFException.REASON_UNKNOWN_LANGUAGE, - "unsupported language: " + lang); - } - - // create the engine and initialize it. if anything goes wrong - // except. - try { - Class engineClass = - (classLoader == null) - ? Class.forName(engineClassName) - : classLoader.loadClass(engineClassName); - final BSFEngine engf = (BSFEngine) engineClass.newInstance(); - final BSFManager thisf = this; - final String langf = lang; - final Vector dbf = declaredBeans; - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - engf.initialize(thisf, langf, dbf); - return null; - } - }); - eng = engf; - loadedEngines.put(lang, eng); - pcs.addPropertyChangeListener(eng); - return eng; - } catch (PrivilegedActionException prive) { - - logger.error("Exception :", prive); - throw (BSFException) prive.getException(); - } catch (Throwable t) { - - logger.error("Exception :", t); - throw new BSFException(BSFException.REASON_OTHER_ERROR, - "unable to load language: " + lang, - t); - } - } - - /** - * return a handle to a bean registered in the bean registry by the - * application or a scripting engine. Returns null if bean is not found. - * - * @param beanName name of bean to look up - * - * @return the bean if its found or null - */ - public Object lookupBean(String beanName) { - logger.debug("BSFManager:lookupBean"); - - try { - return ((BSFDeclaredBean)objectRegistry.lookup(beanName)).bean; - } catch (IllegalArgumentException e) { - - logger.debug("Exception :", e); - return null; - } - } - - /** - * Registering a bean allows a scripting engine or the application to - * access that bean by name and to manipulate it. - * - * @param beanName name to register under - * @param bean the bean to register - */ - public void registerBean(String beanName, Object bean) { - logger.debug("BSFManager:registerBean"); - - BSFDeclaredBean tempBean; - - if(bean == null) { - tempBean = new BSFDeclaredBean(beanName, null, null); - } else { - - tempBean = new BSFDeclaredBean(beanName, bean, bean.getClass()); - } - objectRegistry.register(beanName, tempBean); - } - - /** - * Register a scripting engine in the static registry of the - * BSFManager. - * - * @param lang string identifying language - * @param engineClassName fully qualified name of the class interfacing - * the language to BSF. - * @param extensions array of file extensions that should be mapped to - * this language type. may be null. - */ - public static void registerScriptingEngine(String lang, - String engineClassName, - String[] extensions) { - registeredEngines.put(lang, engineClassName); - if (extensions != null) { - for (int i = 0; i < extensions.length; i++) { - String langstr = (String) extn2Lang.get(extensions[i]); - langstr = (langstr == null) ? lang : lang + ":" + langstr; - extn2Lang.put(extensions[i], langstr); - } - } - } - - /** - * Set the class loader for those that need to use it. Default is he - * who loaded me or null (i.e., its Class.forName). - * - * @param classLoader the class loader to use. - */ - public void setClassLoader(ClassLoader classLoader) { - logger.debug("BSFManager:setClassLoader"); - - pcs.firePropertyChange("classLoader", this.classLoader, classLoader); - this.classLoader = classLoader; - } - - /** - * Set the classpath for those that need to use it. Default is the value - * of the java.class.path property. - * - * @param classPath the classpath to use - */ - public void setClassPath(String classPath) { - logger.debug("BSFManager:setClassPath"); - - pcs.firePropertyChange("classPath", this.classPath, classPath); - this.classPath = classPath; - } - - /** - * Set the object registry used by this manager. By default a new - * one is created when the manager is new'ed and this overwrites - * that one. - * - * @param objectRegistry the registry to use - */ - public void setObjectRegistry(ObjectRegistry objectRegistry) { - logger.debug("BSFManager:setObjectRegistry"); - - this.objectRegistry = objectRegistry; - } - - /** - * Temporary directory to put stuff into (for those who need to). Note - * that unless this directory is in the classpath or unless the - * classloader knows to look in here, any classes here will not - * be found! BSFManager provides a service method to load a class - * which uses either the classLoader provided by the class loader - * property or, if that fails, a class loader which knows to load from - * the tempdir to try to load the class. Default value of tempDir - * is "." (current working dir). - * - * @param tempDir the temporary directory - */ - public void setTempDir(String tempDir) { - logger.debug("BSFManager:setTempDir"); - - pcs.firePropertyChange("tempDir", this.tempDir, tempDir); - this.tempDir = tempDir; - } - - /** - * Gracefully terminate all engines - */ - public void terminate() { - logger.debug("BSFManager:terminate"); - - Enumeration enginesEnum = loadedEngines.elements(); - BSFEngine engine; - while (enginesEnum.hasMoreElements()) { - engine = (BSFEngine) enginesEnum.nextElement(); - engine.terminate(); - } - - loadedEngines = new Hashtable(); - } - - /** - * Undeclare a previously declared bean. This removes the bean from - * the list of declared beans in the manager as well as asks every - * running engine to undeclared the bean. As with above, if any - * of the engines except when asked to undeclare, this method does - * not catch that exception. Quietly returns if the bean is unknown. - * - * @param beanName name of bean to undeclare - * - * @exception BSFException if any of the languages that are already - * running decides to throw an exception when asked to - * undeclare this bean. - */ - public void undeclareBean(String beanName) throws BSFException { - logger.debug("BSFManager:undeclareBean"); - - unregisterBean(beanName); - - BSFDeclaredBean tempBean = null; - boolean found = false; - for (Iterator i = declaredBeans.iterator(); i.hasNext();) { - tempBean = (BSFDeclaredBean) i.next(); - if (tempBean.name.equals(beanName)) { - found = true; - break; - } - } - - if (found) { - declaredBeans.removeElement(tempBean); - - Enumeration enginesEnum = loadedEngines.elements(); - while (enginesEnum.hasMoreElements()) { - BSFEngine engine = (BSFEngine) enginesEnum.nextElement(); - engine.undeclareBean(tempBean); - } - } - } - - /** - * Unregister a previously registered bean. Silent if name is not found. - * - * @param beanName name of bean to unregister - */ - public void unregisterBean(String beanName) { - logger.debug("BSFManager:unregisterBean"); - - objectRegistry.unregister(beanName); - } -} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/bsf/Languages.properties b/src/main/java/com/volmit/iris/util/bsf/Languages.properties deleted file mode 100644 index 6c5e83281..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/Languages.properties +++ /dev/null @@ -1,50 +0,0 @@ -# -# Iris is a World Generator for Minecraft Bukkit Servers -# Copyright (c) 2021 Arcane Arts (Volmit Software) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program 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 for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -# List of script types and their associated scripting engines -# -# languageDescriptor = engineClass, ext1|ext2|... {, codebaseURL, ...} -# -# where exti are extensions for the language. Note that we leave -# all the engines enabled now and allow them to fail at load time. -# This way engines can be added by just adding to the classpath -# without having to edit this file. Cheating, really, but it works. -# -javascript = com.volmit.iris.util.bsf.engines.javascript.JavaScriptEngine, js -jacl = com.volmit.iris.util.bsf.engines.jacl.JaclEngine, jacl -netrexx = com.volmit.iris.util.bsf.engines.netrexx.NetRexxEngine, nrx -java = com.volmit.iris.util.bsf.engines.java.JavaEngine, java -javaclass = com.volmit.iris.util.bsf.engines.javaclass.JavaClassEngine, class -bml = org.apache.bml.ext.BMLEngine, bml -vbscript = com.volmit.iris.util.bsf.engines.activescript.ActiveScriptEngine, vbs -jscript = com.volmit.iris.util.bsf.engines.activescript.ActiveScriptEngine, jss -perlscript = com.volmit.iris.util.bsf.engines.activescript.ActiveScriptEngine, pls -perl = com.volmit.iris.util.bsf.engines.perl.PerlEngine, pl -jpython = com.volmit.iris.util.bsf.engines.jpython.JPythonEngine, py -jython = com.volmit.iris.util.bsf.engines.jython.JythonEngine, py -lotusscript = com.volmit.iris.util.bsf.engines.lotusscript.LsEngine, lss -xslt = com.volmit.iris.util.bsf.engines.xslt.XSLTEngine, xslt -pnuts = pnuts.ext.PnutsBSFEngine, pnut -beanbasic = com.volmit.iris.util.bsf.engines.beanbasic.BeanBasicEngine, bb -beanshell = bsh.util.BeanShellBSFEngine, bsh -ruby = org.jruby.javasupport.bsf.JRubyEngine, rb -judoscript = com.judoscript.BSFJudoEngine, judo|jud -groovy = org.codehaus.groovy.bsf.GroovyEngine, groovy|gy -objectscript = oscript.bsf.ObjectScriptEngine, os -prolog = ubc.cs.JLog.Extras.BSF.JLogBSFEngine, plog|prolog -rexx = org.rexxla.bsf.engines.rexx.RexxEngine, rex | rexx | cls | rxj | rxs diff --git a/src/main/java/com/volmit/iris/util/bsf/Main.java b/src/main/java/com/volmit/iris/util/bsf/Main.java deleted file mode 100644 index 10fbfe6a6..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/Main.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.bsf; - -import java.awt.Frame; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.Reader; -import java.util.Hashtable; - -import com.volmit.iris.util.bsf.util.CodeBuffer; -import com.volmit.iris.util.bsf.util.IOUtils; - -/** - * This is the main driver for BSF to be run on the command line - * to eval/exec/compile scripts directly. - * - * @author Sanjiva Weerawarana - * @author Matthew J. Duftler - * @author Sam Ruby - */ -public class Main { - private static String ARG_IN = "-in"; - private static String ARG_LANG = "-lang"; - private static String ARG_MODE = "-mode"; - private static String ARG_OUT = "-out"; - private static String ARG_VAL_EVAL = "eval"; - private static String ARG_VAL_EXEC = "exec"; - private static String ARG_VAL_COMPILE = "compile"; - private static String DEFAULT_IN_FILE_NAME = ""; - private static String DEFAULT_MODE = ARG_VAL_EVAL; - private static String DEFAULT_CLASS_NAME = "Test"; - - /** - * Static driver to be able to run BSF scripts from the command line. - * - * @param args command line arguments - * - * @exception IOException if any I/O error while loading script - */ - public static void main(String[] args) throws IOException { - try { - if ((args.length == 0) || (args.length % 2 != 0)) { - printHelp(); - System.exit(1); - } - - Hashtable argsTable = new Hashtable(); - - argsTable.put(ARG_OUT, DEFAULT_CLASS_NAME); - argsTable.put(ARG_MODE, DEFAULT_MODE); - - for (int i = 0; i < args.length; i += 2) { - argsTable.put(args[i], args[i + 1]); - } - - String inFileName = (String) argsTable.get(ARG_IN); - String language = (String) argsTable.get(ARG_LANG); - - if (language == null) { - if (inFileName != null) { - language = BSFManager.getLangFromFilename(inFileName); - } else { - throw new BSFException( - BSFException.REASON_OTHER_ERROR, - "unable to determine language"); - } - } - - Reader in; - - if (inFileName != null) { - in = new FileReader(inFileName); - } else { - in = new InputStreamReader(System.in); - inFileName = DEFAULT_IN_FILE_NAME; - } - - BSFManager mgr = new BSFManager(); - String mode = (String) argsTable.get(ARG_MODE); - - if (mode.equals(ARG_VAL_COMPILE)) { - String outClassName = (String) argsTable.get(ARG_OUT); - FileWriter out = new FileWriter(outClassName + ".java"); - PrintWriter pw = new PrintWriter(out); - - CodeBuffer cb = new CodeBuffer(); - cb.setClassName(outClassName); - mgr.compileScript( - language, - inFileName, - 0, - 0, - IOUtils.getStringFromReader(in), - cb); - cb.print(pw, true); - out.close(); - } else { - if (mode.equals(ARG_VAL_EXEC)) { - mgr.exec(language, inFileName, 0, 0, IOUtils.getStringFromReader(in)); - } else { /* eval */ - Object obj = mgr.eval(language, inFileName, 0, 0, IOUtils.getStringFromReader(in)); - - - // Try to display the result. - - if (obj instanceof java.awt.Component) { - Frame f; - if (obj instanceof Frame) { - f = (Frame) obj; - } else { - f = new Frame ("BSF Result: " + inFileName); - f.add ((java.awt.Component) obj); - } - // Add a window listener to quit on closing. - f.addWindowListener( - new WindowAdapter () { - public void windowClosing (WindowEvent e) { - System.exit (0); - } - } - ); - f.pack (); - // f.show(); // javac 1.5 warns to use f.show(), Apache build scripts abort as a result :( - f.setVisible(true); // available since Java 1.1 - } else { - System.err.println("Result: " + obj); - - } - - System.err.println("Result: " + obj); - } - } - } catch (BSFException e) { - e.printStackTrace(); - } - } - - private static void printHelp() { - System.err.println("Usage:"); - System.err.println(); - System.err.println(" java " + Main.class.getName() + " [args]"); - System.err.println(); - System.err.println(" args:"); - System.err.println(); - System.err.println( - " [-in fileName] default: " + DEFAULT_IN_FILE_NAME); - System.err.println( - " [-lang languageName] default: " - + ""); - System.err.println( - " [-mode (eval|exec|compile)] default: " + DEFAULT_MODE); - System.err.println(); - System.err.println( - " Additional args used only if -mode is " + "set to \"compile\":"); - System.err.println(); - System.err.println( - " [-out className] default: " + DEFAULT_CLASS_NAME); - } -} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/jacl/BSFCommand.java b/src/main/java/com/volmit/iris/util/bsf/engines/jacl/BSFCommand.java deleted file mode 100644 index 9c1702d35..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/engines/jacl/BSFCommand.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.engines.jacl; - -import com.volmit.iris.util.bsf.BSFEngine; -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; -import com.volmit.iris.util.bsf.util.EngineUtils; - -import tcl.lang.Command; -import tcl.lang.Interp; -import tcl.lang.ReflectObject; -import tcl.lang.TCL; -import tcl.lang.TclException; -import tcl.lang.TclObject; - -// class used to add "bsf" command to the Jacl runtime -class BSFCommand implements Command { - BSFManager mgr; - BSFEngine jengine; - - BSFCommand (BSFManager mgr, BSFEngine jengine) { - this.mgr = mgr; - this.jengine = jengine; - } - public void cmdProc (Interp interp, - TclObject argv[]) throws TclException { - if (argv.length < 2) { - interp.setResult ("invalid # of args; usage: bsf " + - "lookupBean|registerBean|unregisterBean|addEventListener args"); - throw new TclException (TCL.ERROR); - } - - String op = argv[1].toString (); - - if (op.equals ("lookupBean")) { - if (argv.length != 3) { - interp.setResult ("invalid # of args; usage: bsf " + - "lookupBean name-of-bean"); - throw new TclException (TCL.ERROR); - } - - String beanName = argv[2].toString (); - Object bean = mgr.lookupBean (beanName); - if (bean == null) { - interp.setResult ("unknown object: " + beanName); - throw new TclException (TCL.ERROR); - } - interp.setResult (ReflectObject.newInstance (interp, bean.getClass (), - bean)); - - } else if (op.equals ("registerBean")) { - if (argv.length != 4) { - interp.setResult ("invalid # of args; usage: bsf " + - "registerBean name-of-bean bean"); - throw new TclException (TCL.ERROR); - } - mgr.registerBean (argv[2].toString (), - ReflectObject.get (interp, argv[3])); - interp.setResult (""); - - } else if (op.equals ("unregisterBean")) { - if (argv.length != 3) { - interp.setResult ("invalid # of args; usage: bsf " + - "unregisterBean name-of-bean"); - throw new TclException (TCL.ERROR); - } - mgr.unregisterBean (argv[2].toString ()); - interp.setResult (""); - - } else if (op.equals ("addEventListener")) { - if (argv.length != 6) { - interp.setResult ("invalid # of args; usage: bsf " + - "addEventListener object event-set-name filter " + - "script-to-run"); - throw new TclException (TCL.ERROR); - } - try { - // usage: bsf addEventListener object event-set filter script - String filter = argv[4].toString (); - filter = filter.equals ("") ? null : filter; - EngineUtils.addEventListener (ReflectObject.get (interp, argv[2]), - argv[3].toString (), filter, - jengine, mgr, "", 0, 0, - argv[5].toString ()); - } catch (BSFException e) { - e.printStackTrace (); - interp.setResult ("got BSF exception: " + e.getMessage ()); - throw new TclException (TCL.ERROR); - } - } - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/jacl/JaclEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/jacl/JaclEngine.java deleted file mode 100644 index 57cdfbbf0..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/engines/jacl/JaclEngine.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.engines.jacl; - -import java.util.Vector; - -import com.volmit.iris.util.bsf.BSFDeclaredBean; -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; -import com.volmit.iris.util.bsf.util.BSFEngineImpl; - -import tcl.lang.Interp; -import tcl.lang.ReflectObject; -import tcl.lang.TclDouble; -import tcl.lang.TclException; -import tcl.lang.TclInteger; -import tcl.lang.TclObject; -import tcl.lang.TclString; - -/** - * This is the interface to Scriptics's Jacl (Tcl) from the - * Bean Scripting Framework. - *

- * - * @author Sanjiva Weerawarana - */ - -public class JaclEngine extends BSFEngineImpl { - /* the Jacl interpretor object */ - private Interp interp; - - /** - * - * @param method The name of the method to call. - * @param args an array of arguments to be - * passed to the extension, which may be either - * Vectors of Nodes, or Strings. - */ - public Object call (Object obj, String method, Object[] args) - throws BSFException { - StringBuffer tclScript = new StringBuffer (method); - if (args != null) { - for( int i = 0 ; i < args.length ; i++ ) { - tclScript.append (" "); - tclScript.append (args[i].toString ()); - } - } - return eval ("", 0, 0, tclScript.toString ()); - } - /** - * Declare a bean - */ - public void declareBean (BSFDeclaredBean bean) throws BSFException { - String expr = "set " + bean.name + " [bsf lookupBean \"" + bean.name + - "\"]"; - eval ("", 0, 0, expr); - } - /** - * This is used by an application to evaluate a string containing - * some expression. - */ - public Object eval (String source, int lineNo, int columnNo, - Object oscript) throws BSFException { - String script = oscript.toString (); - try { - interp.eval (script); - TclObject result = interp.getResult(); - Object internalRep = result.getInternalRep(); - - // if the object has a corresponding Java type, unwrap it - if (internalRep instanceof ReflectObject) - return ReflectObject.get(interp,result); - if (internalRep instanceof TclString) - return result.toString(); - if (internalRep instanceof TclDouble) - return new Double(TclDouble.get(interp,result)); - if (internalRep instanceof TclInteger) - return new Integer(TclInteger.get(interp,result)); - - return result; - } catch (TclException e) { - throw new BSFException (BSFException.REASON_EXECUTION_ERROR, - "error while eval'ing Jacl expression: " + - interp.getResult (), e); - } - } - /** - * Initialize the engine. - */ - public void initialize (BSFManager mgr, String lang, - Vector declaredBeans) throws BSFException { - super.initialize (mgr, lang, declaredBeans); - - // create interpreter - interp = new Interp(); - - // register the extension that user's can use to get at objects - // registered by the app - interp.createCommand ("bsf", new BSFCommand (mgr, this)); - - // Make java functions be available to Jacl - try { - interp.eval("jaclloadjava"); - } catch (TclException e) { - throw new BSFException (BSFException.REASON_OTHER_ERROR, - "error while loading java package: " + - interp.getResult (), e); - } - - int size = declaredBeans.size (); - for (int i = 0; i < size; i++) { - declareBean ((BSFDeclaredBean) declaredBeans.elementAt (i)); - } - } - - /** - * Undeclare a previously declared bean. - */ - public void undeclareBean (BSFDeclaredBean bean) throws BSFException { - eval ("", 0, 0, "set " + bean.name + " \"\""); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/java/JavaEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/java/JavaEngine.java deleted file mode 100644 index 7b2405449..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/engines/java/JavaEngine.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.engines.java; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.lang.reflect.Method; -import java.util.Hashtable; -import java.util.Vector; - -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; -import com.volmit.iris.util.bsf.util.BSFEngineImpl; -import com.volmit.iris.util.bsf.util.CodeBuffer; -import com.volmit.iris.util.bsf.util.EngineUtils; -import com.volmit.iris.util.bsf.util.JavaUtils; -import com.volmit.iris.util.bsf.util.MethodUtils; -import com.volmit.iris.util.bsf.util.ObjInfo; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This is the interface to Java from the - * Bean Scripting Framework. - *

- * The Java code must be written script-style -- that is, just the body of - * the function, without class or method headers or footers. - * The JavaEngine will generate those via a "boilerplate" wrapper: - *

- * 
- * import java.lang.*;
- * import java.util.*;
- * public class $$CLASSNAME$$ {
- *   static public Object BSFJavaEngineEntry(com.volmit.iris.util.bsf.BSFManager bsf) {
- *     // Your code will be placed here
- *   }
- * }
- * 
- * 
- * $$CLASSNAME$$ will be replaced by a generated classname of the form - * BSFJava*, and the bsf parameter can be used to retrieve application - * objects registered with the Bean Scripting Framework. - *

- * If you use the placeholder string $$CLASSNAME$$ elsewhere - * in your script -- including within text strings -- BSFJavaEngine will - * replace it with the generated name of the class before the Java code - * is compiled. - *

- *

Hazards:

- *

- * NOTE that it is your responsibility to convert the code into an acceptable - * Java string. If you're invoking the JavaEngine directly (as in the - * JSPLikeInJava example) that means \"quoting\" characters that would - * otherwise cause trouble. - *

- * ALSO NOTE that it is your responsibility to return an object, or null in - * lieu thereof! - *

- * Since the code has to be compiled to a Java classfile, invoking it involves - * a fair amount of computation to load and execute the compiler. We are - * currently making an attempt to manage that by caching the class - * after it has been loaded, but the indexing is fairly primitive. It has - * been suggested that the Bean Scripting Framework may want to support - * preload-and-name-script and execute-preloaded-script-by-name options to - * provide better control over when and how much overhead occurs. - *

- * @author Joe Kesselman - */ -public class JavaEngine extends BSFEngineImpl { - Class javaclass = null; - static Hashtable codeToClass = new Hashtable(); - static String serializeCompilation = ""; - static String placeholder = "$$CLASSNAME$$"; - String minorPrefix; - - private Log logger = LogFactory.getLog(this.getClass().getName()); - - /** - * Create a scratchfile, open it for writing, return its name. - * Relies on the filesystem to provide us with uniqueness testing. - * NOTE THAT uniqueFileOffset continues to count; we don't want to - * risk reusing a classname we have previously loaded in this session - * even if the classfile has been deleted. - */ - private int uniqueFileOffset = -1; - - private class GeneratedFile { - File file = null; - FileOutputStream fos = null; - String className = null; - GeneratedFile(File file, FileOutputStream fos, String className) { - this.file = file; - this.fos = fos; - this.className = className; - } - } - - /** - * Constructor. - */ - public JavaEngine () { - // Do compilation-possible check here?????????????? - } - - public Object call (Object object, String method, Object[] args) - throws BSFException - { - throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE, - "call() is not currently supported by JavaEngine"); - } - - public void compileScript (String source, int lineNo, int columnNo, - Object script, CodeBuffer cb) throws BSFException { - ObjInfo oldRet = cb.getFinalServiceMethodStatement (); - - if (oldRet != null && oldRet.isExecutable ()) { - cb.addServiceMethodStatement (oldRet.objName + ";"); - } - - cb.addServiceMethodStatement (script.toString ()); - cb.setFinalServiceMethodStatement (null); - } - - /** - * This is used by an application to evaluate a string containing - * some expression. It should store the "bsf" handle where the - * script can get to it, for callback purposes. - *

- * Note that Java compilation imposes serious overhead, - * but in exchange you get full Java performance - * once the classes have been created (minus the cache lookup cost). - *

- * Nobody knows whether javac is threadsafe. - * I'm going to serialize access to protect it. - *

- * There is no published API for invoking javac as a class. There's a trick - * that seems to work for Java 1.1.x, but it stopped working in Java 1.2. - * We will attempt to use it, then if necessary fall back on invoking - * javac via the command line. - */ - public Object eval (String source, int lineNo, int columnNo, - Object oscript) throws BSFException - { - Object retval = null; - String classname = null; - GeneratedFile gf = null; - - String basescript = oscript.toString(); - String script = basescript; // May be altered by $$CLASSNAME$$ expansion - - try { - // Do we already have a class exactly matching this code? - javaclass = (Class)codeToClass.get(basescript); - - if(javaclass != null) { - classname=javaclass.getName(); - } else { - gf = openUniqueFile(tempDir, "BSFJava",".java"); - if( gf == null) { - throw new BSFException("couldn't create JavaEngine scratchfile"); - } - // Obtain classname - classname = gf.className; - - // Write the kluge header to the file. - gf.fos.write(("import java.lang.*;"+ - "import java.util.*;"+ - "public class "+classname+" {\n" + - " static public Object BSFJavaEngineEntry(com.volmit.iris.util.bsf.BSFManager bsf) {\n") - .getBytes()); - - // Edit the script to replace placeholder with the generated - // classname. Note that this occurs _after_ the cache was checked! - int startpoint = script.indexOf(placeholder); - int endpoint; - if(startpoint >= 0) { - StringBuffer changed = new StringBuffer(); - for(; startpoint >=0; startpoint = script.indexOf(placeholder,startpoint)) { - changed.setLength(0); // Reset for 2nd pass or later - if(startpoint > 0) { - changed.append(script.substring(0,startpoint)); - } - changed.append(classname); - endpoint = startpoint+placeholder.length(); - if(endpoint < script.length()) { - changed.append(script.substring(endpoint)); - } - script = changed.toString(); - } - } - - // MJD - debug -// BSFDeclaredBean tempBean; -// String className; -// -// for (int i = 0; i < declaredBeans.size (); i++) { -// tempBean = (BSFDeclaredBean) declaredBeans.elementAt (i); -// className = StringUtils.getClassName (tempBean.bean.getClass ()); -// -// gf.fos.write ((className + " " + -// tempBean.name + " = (" + className + -// ")bsf.lookupBean(\"" + -// tempBean.name + "\");").getBytes ()); -// } - // MJD - debug - - // Copy the input to the file. - // Assumes all available -- probably mistake, but same as other engines. - gf.fos.write(script.getBytes()); - // Close the method and class - gf.fos.write(("\n }\n}\n").getBytes()); - gf.fos.close(); - - // Compile through Java to .class file - // May not be threadsafe. Serialize access on static object: - synchronized(serializeCompilation) { - JavaUtils.JDKcompile(gf.file.getPath(), classPath); - } - - // Load class. - javaclass = EngineUtils.loadClass(mgr, classname); - - // Stash class for reuse - codeToClass.put(basescript, javaclass); - } - - Object[] callArgs = {mgr}; - retval = internalCall(this,"BSFJavaEngineEntry",callArgs); - } - - - catch(Exception e) { - e.printStackTrace (); - throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage ()); - } finally { - // Cleanup: delete the .java and .class files - -// if(gf!=null && gf.file!=null && gf.file.exists()) -// gf.file.delete(); // .java file - - - if(classname!=null) { - // Generated class - File file = new File(tempDir+File.separatorChar+classname+".class"); -// if(file.exists()) -// file.delete(); - - // Search for and clean up minor classes, classname$xxx.class - file = new File(tempDir); // ***** Is this required? - minorPrefix = classname+"$"; // Indirect arg to filter - String[] minorClassfiles = file.list(new FilenameFilter() - { - // Starts with classname$ and ends with .class - public boolean accept(File dir,String name) { - return - (0 == name.indexOf(minorPrefix)) - && - (name.lastIndexOf(".class") == name.length()-6); - } - }); - for(int i = 0; i < minorClassfiles.length; ++i) { - file = new File(minorClassfiles[i]); -// file.delete(); - } - } - } - return retval; - } - - public void initialize (BSFManager mgr, String lang, - Vector declaredBeans) throws BSFException { - super.initialize (mgr, lang, declaredBeans); - } - /** - * Return an object from an extension. - * @param object Object on which to make the internal_call (ignored). - * @param method The name of the method to internal_call. - * @param args an array of arguments to be - * passed to the extension, which may be either - * Vectors of Nodes, or Strings. - */ - Object internalCall (Object object, String method, Object[] args) - throws BSFException - { - //***** ISSUE: Only static methods are currently supported - Object retval = null; - try { - if(javaclass != null) { - //***** This should call the lookup used in BML, for typesafety - Class[] argtypes = new Class[args.length]; - for(int i=0; i0;--i,++uniqueFileOffset) { - // Probably a timing hazard here... *************** - try { - className = prefix+uniqueFileOffset; - file = new File(directory+File.separatorChar+className+suffix); - if(file != null && !file.exists()) { - fos = new FileOutputStream(file); - } - } - catch(Exception e) { - // File could not be opened for write, or Security Exception - // was thrown. If someone else created the file before we could - // open it, that's probably a threading conflict and we don't - // bother reporting it. - if(!file.exists()) { - logger.error("openUniqueFile: unexpected ", e); - } - } - } - if(fos==null) { - logger.error("openUniqueFile: Failed "+max+"attempts."); - } else { - gf = new GeneratedFile(file,fos,className); - } - return gf; - } -} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/javaclass/JavaClassEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/javaclass/JavaClassEngine.java deleted file mode 100644 index c79007d87..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/engines/javaclass/JavaClassEngine.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.engines.javaclass; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.util.BSFEngineImpl; -import com.volmit.iris.util.bsf.util.MethodUtils; - -/** - * This is the interface to scripts consisting of Java objects from the - * Bean Scripting Framework. - * - * @author Sanjiva Weerawarana - */ -public class JavaClassEngine extends BSFEngineImpl { - /** - * call the named method of the given object. If object is an instance - * of Class, then the call is a static call on that object. If not, its - * an instance method call or a static call (as per Java) on the given - * object. - */ - public Object call (Object object, String method, Object[] args) - throws BSFException { - // determine arg types - Class[] argTypes = null; - if (args != null) { - argTypes = new Class[args.length]; - for (int i = 0; i < args.length; i++) { - argTypes[i] = (args[i] != null) ? args[i].getClass () : null; - } - } - - // now find method with the right signature, call it and return result - try { - Method m = MethodUtils.getMethod (object, method, argTypes); - return m.invoke (object, args); - } catch (Exception e) { - // something went wrong while invoking method - Throwable t = (e instanceof InvocationTargetException) ? - ((InvocationTargetException)e).getTargetException () : - null; - throw new BSFException (BSFException.REASON_OTHER_ERROR, - "method invocation failed: " + e + - ((t==null)?"":(" target exception: "+t)), t); - } - } - /** - * This is used by an application to evaluate an object containing - * some expression - clearly not possible for compiled code .. - */ - public Object eval (String source, int lineNo, int columnNo, - Object oscript) throws BSFException { - throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE, - "Java bytecode engine can't evaluate expressions"); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/javascript/JavaScriptEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/javascript/JavaScriptEngine.java deleted file mode 100644 index 12051a811..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/engines/javascript/JavaScriptEngine.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.engines.javascript; - -import java.util.Iterator; -import java.util.Vector; - -import com.volmit.iris.util.bsf.BSFDeclaredBean; -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; -import com.volmit.iris.util.bsf.util.BSFEngineImpl; -import com.volmit.iris.util.bsf.util.BSFFunctions; -import org.mozilla.javascript.Context; -import org.mozilla.javascript.EvaluatorException; -import org.mozilla.javascript.Function; -import org.mozilla.javascript.ImporterTopLevel; -import org.mozilla.javascript.JavaScriptException; -import org.mozilla.javascript.NativeJavaObject; -import org.mozilla.javascript.Scriptable; -import org.mozilla.javascript.WrappedException; -import org.mozilla.javascript.Wrapper; - -/** - * This is the interface to Netscape's Rhino (JavaScript) from the - * Bean Scripting Framework. - *

- * The original version of this code was first written by Adam Peller - * for use in LotusXSL. Sanjiva took his code and adapted it for BSF. - * - * @author Adam Peller - * @author Sanjiva Weerawarana - * @author Matthew J. Duftler - * @author Norris Boyd - */ -public class JavaScriptEngine extends BSFEngineImpl { - /** - * The global script object, where all embedded functions are defined, - * as well as the standard ECMA "core" objects. - */ - private Scriptable global; - - /** - * Return an object from an extension. - * @param object Object on which to make the call (ignored). - * @param method The name of the method to call. - * @param args an array of arguments to be - * passed to the extension, which may be either - * Vectors of Nodes, or Strings. - */ - public Object call(Object object, String method, Object[] args) - throws BSFException { - - Object retval = null; - Context cx; - - try { - cx = Context.enter(); - - // REMIND: convert arg list Vectors here? - - Object fun = global.get(method, global); - // NOTE: Source and line arguments are nonsense in a call(). - // Any way to make these arguments *sensible? - if (fun == Scriptable.NOT_FOUND) - throw new EvaluatorException("function " + method + - " not found.", "none", 0); - - cx.setOptimizationLevel(-1); - cx.setGeneratingDebug(false); - cx.setGeneratingSource(false); - cx.setOptimizationLevel(0); - cx.setDebugger(null, null); - - retval = - ((Function) fun).call(cx, global, global, args); - -// ScriptRuntime.call(cx, fun, global, args, global); - - if (retval instanceof Wrapper) - retval = ((Wrapper) retval).unwrap(); - } - catch (Throwable t) { - handleError(t); - } - finally { - Context.exit(); - } - return retval; - } - - public void declareBean(BSFDeclaredBean bean) throws BSFException { - if ((bean.bean instanceof Number) || - (bean.bean instanceof String) || - (bean.bean instanceof Boolean)) { - global.put(bean.name, global, bean.bean); - } - else { - // Must wrap non-scriptable objects before presenting to Rhino - Scriptable wrapped = Context.toObject(bean.bean, global); - global.put(bean.name, global, wrapped); - } - } - - /** - * This is used by an application to evaluate a string containing - * some expression. - */ - public Object eval(String source, int lineNo, int columnNo, Object oscript) - throws BSFException { - - String scriptText = oscript.toString(); - Object retval = null; - Context cx; - - try { - cx = Context.enter(); - - cx.setOptimizationLevel(-1); - cx.setGeneratingDebug(false); - cx.setGeneratingSource(false); - cx.setOptimizationLevel(0); - cx.setDebugger(null, null); - - retval = cx.evaluateString(global, scriptText, - source, lineNo, - null); - - if (retval instanceof NativeJavaObject) - retval = ((NativeJavaObject) retval).unwrap(); - - } - catch (Throwable t) { // includes JavaScriptException, rethrows Errors - handleError(t); - } - finally { - Context.exit(); - } - return retval; - } - - private void handleError(Throwable t) throws BSFException { - if (t instanceof WrappedException) - t = ((WrappedException) t).getWrappedException(); - - String message = null; - Throwable target = t; - - if (t instanceof JavaScriptException) { - message = t.getLocalizedMessage(); - - // Is it an exception wrapped in a JavaScriptException? - Object value = ((JavaScriptException) t).getValue(); - if (value instanceof Throwable) { - // likely a wrapped exception from a LiveConnect call. - // Display its stack trace as a diagnostic - target = (Throwable) value; - } - } - else if (t instanceof EvaluatorException || - t instanceof SecurityException) { - message = t.getLocalizedMessage(); - } - else if (t instanceof RuntimeException) { - message = "Internal Error: " + t.toString(); - } - else if (t instanceof StackOverflowError) { - message = "Stack Overflow"; - } - - if (message == null) - message = t.toString(); - - if (t instanceof Error && !(t instanceof StackOverflowError)) { - // Re-throw Errors because we're supposed to let the JVM see it - // Don't re-throw StackOverflows, because we know we've - // corrected the situation by aborting the loop and - // a long stacktrace would end up on the user's console - throw (Error) t; - } - else { - throw new BSFException(BSFException.REASON_OTHER_ERROR, - "JavaScript Error: " + message, - target); - } - } - - /** - * Initialize the engine. - * Put the manager into the context-manager - * map hashtable too. - */ - public void initialize(BSFManager mgr, String lang, Vector declaredBeans) - throws BSFException { - - super.initialize(mgr, lang, declaredBeans); - - // Initialize context and global scope object - try { - Context cx = Context.enter(); - global = new ImporterTopLevel(cx); - Scriptable bsf = Context.toObject(new BSFFunctions(mgr, this), global); - global.put("bsf", global, bsf); - - for(Iterator it = declaredBeans.iterator(); it.hasNext();) { - declareBean((BSFDeclaredBean) it.next()); - } - } - catch (Throwable t) { - - } - finally { - Context.exit(); - } - } - - public void undeclareBean(BSFDeclaredBean bean) throws BSFException { - global.delete(bean.name); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/jython/JythonEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/jython/JythonEngine.java deleted file mode 100644 index 2ed1928b7..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/engines/jython/JythonEngine.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.engines.jython; - -import java.io.ByteArrayInputStream; -import java.util.Vector; - -import com.volmit.iris.util.bsf.BSFDeclaredBean; -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; -import com.volmit.iris.util.bsf.util.BSFEngineImpl; -import com.volmit.iris.util.bsf.util.BSFFunctions; -import org.python.core.Py; -import org.python.core.PyException; -import org.python.core.PyJavaInstance; -import org.python.core.PyObject; -import org.python.util.InteractiveInterpreter; - -/** - * This is the interface to Jython (http://www.jython.org/) from BSF. - * It's derived from the JPython 1.x engine - * - * @author Sanjiva Weerawarana - * @author Finn Bock - * @author Chuck Murcko - */ - -public class JythonEngine extends BSFEngineImpl { - BSFPythonInterpreter interp; - - /** - * call the named method of the given object. - */ - public Object call (Object object, String method, Object[] args) - throws BSFException { - try { - PyObject[] pyargs = Py.EmptyObjects; - - if (args != null) { - pyargs = new PyObject[args.length]; - for (int i = 0; i < pyargs.length; i++) - pyargs[i] = Py.java2py(args[i]); - } - - if (object != null) { - PyObject o = Py.java2py(object); - return unwrap(o.invoke(method, pyargs)); - } - - PyObject m = interp.get(method); - - if (m == null) - m = interp.eval(method); - if (m != null) { - return unwrap(m.__call__(pyargs)); - } - - return null; - } catch (PyException e) { - throw new BSFException (BSFException.REASON_EXECUTION_ERROR, - "exception from Jython:\n" + e, e); - } - } - - /** - * Declare a bean - */ - public void declareBean (BSFDeclaredBean bean) throws BSFException { - interp.set (bean.name, bean.bean); - } - - /** - * Evaluate an anonymous function (differs from eval() in that apply() - * handles multiple lines). - */ - public Object apply (String source, int lineNo, int columnNo, - Object funcBody, Vector paramNames, - Vector arguments) throws BSFException { - try { - /* We wrapper the original script in a function definition, and - * evaluate the function. A hack, no question, but it allows - * apply() to pretend to work on Jython. - */ - StringBuffer script = new StringBuffer(byteify(funcBody.toString())); - int index = 0; - script.insert(0, "def bsf_temp_fn():\n"); - - while (index < script.length()) { - if (script.charAt(index) == '\n') { - script.insert(index+1, '\t'); - } - index++; - } - - interp.exec (script.toString ()); - - Object result = interp.eval ("bsf_temp_fn()"); - - if (result != null && result instanceof PyJavaInstance) - result = ((PyJavaInstance)result).__tojava__(Object.class); - return result; - } catch (PyException e) { - throw new BSFException (BSFException.REASON_EXECUTION_ERROR, - "exception from Jython:\n" + e, e); - } - } - - /** - * Evaluate an expression. - */ - public Object eval (String source, int lineNo, int columnNo, - Object script) throws BSFException { - try { - Object result = interp.eval (byteify(script.toString ())); - if (result != null && result instanceof PyJavaInstance) - result = ((PyJavaInstance)result).__tojava__(Object.class); - return result; - } catch (PyException e) { - throw new BSFException (BSFException.REASON_EXECUTION_ERROR, - "exception from Jython:\n" + e, e); - } - } - - /** - * Execute a script. - */ - public void exec (String source, int lineNo, int columnNo, - Object script) throws BSFException { - try { - interp.exec (byteify(script.toString ())); - } catch (PyException e) { - throw new BSFException (BSFException.REASON_EXECUTION_ERROR, - "exception from Jython:\n" + e, e); - } - } - - /** - * Execute script code, emulating console interaction. - */ - public void iexec (String source, int lineNo, int columnNo, - Object script) throws BSFException { - String scriptStr = byteify(script.toString()); - int newline = scriptStr.indexOf("\n"); - - if (newline > -1) - scriptStr = scriptStr.substring(0, newline); - - try { - if (interp.buffer.length() > 0) - interp.buffer.append("\n"); - interp.buffer.append(scriptStr); - if (!(interp.runsource(interp.buffer.toString()))) - interp.resetbuffer(); - } catch (PyException e) { - interp.resetbuffer(); - throw new BSFException(BSFException.REASON_EXECUTION_ERROR, - "exception from Jython:\n" + e, e); - } - } - - /** - * Initialize the engine. - */ - public void initialize (BSFManager mgr, String lang, - Vector declaredBeans) throws BSFException { - super.initialize (mgr, lang, declaredBeans); - - // create an interpreter - interp = new BSFPythonInterpreter (); - - // ensure that output and error streams are re-directed correctly - interp.setOut(System.out); - interp.setErr(System.err); - - // register the mgr with object name "bsf" - interp.set ("bsf", new BSFFunctions (mgr, this)); - - // Declare all declared beans to the interpreter - int size = declaredBeans.size (); - for (int i = 0; i < size; i++) { - declareBean ((BSFDeclaredBean) declaredBeans.elementAt (i)); - } - } - - /** - * Undeclare a previously declared bean. - */ - public void undeclareBean (BSFDeclaredBean bean) throws BSFException { - interp.set (bean.name, null); - } - - public Object unwrap(PyObject result) { - if (result != null) { - Object ret = result.__tojava__(Object.class); - if (ret != Py.NoConversion) - return ret; - } - return result; - } - - private String byteify (String orig) { - // Ugh. Jython likes to be fed bytes, rather than the input string. - ByteArrayInputStream bais = - new ByteArrayInputStream(orig.getBytes()); - StringBuffer s = new StringBuffer(); - int c; - - while ((c = bais.read()) >= 0) { - s.append((char)c); - } - - return s.toString(); - } - - private class BSFPythonInterpreter extends InteractiveInterpreter { - - public BSFPythonInterpreter() { - super(); - } - - // Override runcode so as not to print the stack dump - public void runcode(PyObject code) { - try { - this.exec(code); - } catch (PyException exc) { - throw exc; - } - } - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/netrexx/NetRexxEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/netrexx/NetRexxEngine.java deleted file mode 100644 index 40ea27466..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/engines/netrexx/NetRexxEngine.java +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.engines.netrexx; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.PrintWriter; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Hashtable; -import java.util.Vector; - -import com.volmit.iris.util.bsf.BSFDeclaredBean; -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; -import com.volmit.iris.util.bsf.util.BSFEngineImpl; -import com.volmit.iris.util.bsf.util.BSFFunctions; -import com.volmit.iris.util.bsf.util.EngineUtils; -import com.volmit.iris.util.bsf.util.MethodUtils; -import com.volmit.iris.util.bsf.util.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This is the interface to NetRexx from the - * Bean Scripting Framework. - *

- * The NetRexx code must be written script-style, without a "class" or - * "properties" section preceeding the executable code. The NetRexxEngine will - * generate a prefix for this code: - *

- * 
- * class $$CLASSNAME$$;
- * method BSFNetRexxEngineEntry(bsf=com.volmit.iris.util.bsf.BSFManager) public static;
- * 
- * 
- * $$CLASSNAME$$ will be replaced by a generated classname of the form - * BSFNetRexx*, and the bsf parameter can be used to retrieve application - * objects registered with the Bean Scripting Framework. - *

- * If you use the placeholder string $$CLASSNAME$$ elsewhere - * in your script -- including within text strings -- BSFNetRexxEngine will - * replace it with the generated name of the class before the NetRexx code - * is compiled. - *

- * If you need to use full NetRexx functionality, we recommend that your - * NetRexx script define and invoke a "minor class", with or without the - * "dependent" keyword as suits your needs. You'll have to use $$CLASSNAME$$ - * in naming the minor class, since the name of the main class is synthesized; - * for example, to create the minor class "bar" you'd write - * "class $$CLASSNAME$$.Bar". - *

- *

Hazards:

- *

- * Since NetRexx has to be _compiled_ to a Java classfile, invoking it involves - * a fair amount of computation to load and execute the compiler. We are - * currently making an attempt to manage that by caching the class - * after it has been loaded, but the indexing is fairly primitive; we - * hash against the script string to find the class for it. - *

- * Minor-class .class files are now being deleted after the major class loads. - * This coould potentially cause problems. - * - * @author Joe Kesselman - * @author Sanjiva Weerawarana - */ -public class NetRexxEngine extends BSFEngineImpl -{ - BSFFunctions mgrfuncs; - static Hashtable codeToClass=new Hashtable(); - static String serializeCompilation=""; - static String placeholder="$$CLASSNAME$$"; - String minorPrefix; - - private Log logger = LogFactory.getLog(this.getClass().getName()); - - /** - * Create a scratchfile, open it for writing, return its name. - * Relies on the filesystem to provide us with uniqueness testing. - * NOTE THAT uniqueFileOffset continues to count; we don't want to - * risk reusing a classname we have previously loaded in this session - * even if the classfile has been deleted. - * - * I've made the offset static, due to concerns about reuse/reentrancy - * of the NetRexx engine. - */ - private static int uniqueFileOffset=0; - private class GeneratedFile - { - File file=null; - FileOutputStream fos=null; - String className=null; - GeneratedFile(File file,FileOutputStream fos,String className) - { - this.file=file; - this.fos=fos; - this.className=className; - } - } - - // rexxclass used to be an instance variable, on the theory that - // each NetRexxEngine was an instance of a specific script. - // BSF is currently reusing Engines, so caching the class - // no longer makes sense. - // Class rexxclass; - - /** - * Constructor. - */ - public NetRexxEngine () - { - /* - The following line is intended to cause the constructor to - throw a NoClassDefFoundError if the NetRexxC.zip dependency - is not resolved. - - If this line was not here, the problem would not surface until - the actual processing of a script. We want to know all is well - at the time the engine is instantiated, not when we attempt to - process a script. - */ - - new netrexx.lang.BadArgumentException(); - } - /** - * Return an object from an extension. - * @param object object from which to call our static method - * @param method The name of the method to call. - * @param args an array of arguments to be - * passed to the extension, which may be either - * Vectors of Nodes, or Strings. - */ - public Object call (Object object, String method, Object[] args) - throws BSFException - { - throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE, - "NetRexx doesn't currently support call()", - null); - } - /** - * Invoke a static method. - * @param rexxclass Class to invoke the method against - * @param method The name of the method to call. - * @param args an array of arguments to be - * passed to the extension, which may be either - * Vectors of Nodes, or Strings. - */ - Object callStatic(Class rexxclass, String method, Object[] args) - throws BSFException - { - //***** ISSUE: Currently supports only static methods - Object retval = null; - try - { - if (rexxclass != null) - { - //***** This should call the lookup used in BML, for typesafety - Class[] argtypes=new Class[args.length]; - for(int i=0;i - * Note that NetRexx compilation imposes serious overhead -- 11 seconds for - * the first compile, about 3 thereafter -- but in exchange you get - * Java-like speeds once the classes have been created (minus the cache - * lookup cost). - *

- * Nobody knows whether javac is threadsafe. - * I'm going to serialize access to the compilers to protect it. - */ - public Object execEvalShared (String source, int lineNo, int columnNo, - Object oscript,boolean returnsObject) - throws BSFException - { - Object retval=null; - String classname=null; - GeneratedFile gf=null; - - // Moved into the exec process; see comment above. - Class rexxclass=null; - - String basescript=oscript.toString(); - String script=basescript; // May be altered by $$CLASSNAME$$ expansion - - try { - // Do we already have a class exactly matching this code? - rexxclass=(Class)codeToClass.get(basescript); - - if(rexxclass!=null) - - { - logger.debug("NetRexxEngine: Found pre-compiled class" + - " for script '" + basescript + "'"); - classname=rexxclass.getName(); - } - else - { - gf=openUniqueFile(tempDir,"BSFNetRexx",".nrx"); - if(gf==null) - throw new BSFException("couldn't create NetRexx scratchfile"); - - // Obtain classname - classname=gf.className; - - // Decide whether to declare a return type - String returnsDecl=""; - if(returnsObject) - returnsDecl="returns java.lang.Object"; - - // Write the kluge header to the file. - // ***** By doing so we give up the ability to use Property blocks. - gf.fos.write(("class "+classname+";\n") - .getBytes()); - gf.fos.write( - ("method BSFNetRexxEngineEntry(bsf=com.volmit.iris.util.bsf.util.BSFFunctions) "+ - " public static "+returnsDecl+";\n") - .getBytes()); - - // Edit the script to replace placeholder with the generated - // classname. Note that this occurs _after_ the cache was - // checked! - int startpoint,endpoint; - if((startpoint=script.indexOf(placeholder))>=0) - { - StringBuffer changed=new StringBuffer(); - for(; - startpoint>=0; - startpoint=script.indexOf(placeholder,startpoint)) - { - changed.setLength(0); // Reset for 2nd pass or later - if(startpoint>0) - changed.append(script.substring(0,startpoint)); - changed.append(classname); - endpoint=startpoint+placeholder.length(); - if(endpoint0;) - { - file=new File(minor_classfiles[--i]); - file.delete(); - } - } - } - - return retval; - } - public void initialize(BSFManager mgr, String lang,Vector declaredBeans) - throws BSFException - { - super.initialize(mgr, lang, declaredBeans); - mgrfuncs = new BSFFunctions (mgr, this); - } -private GeneratedFile openUniqueFile(String directory,String prefix,String suffix) - { - File file=null,obj=null; - FileOutputStream fos=null; - int max=1000; // Don't try forever - GeneratedFile gf=null; - int i; - String className = null; - for(i=max,++uniqueFileOffset; - fos==null && i>0; - --i,++uniqueFileOffset) - { - // Probably a timing hazard here... *************** - try - { - className = prefix+uniqueFileOffset; - file=new File(directory+File.separatorChar+className+suffix); - obj=new File(directory+File.separatorChar+className+".class"); - if(file!=null && !file.exists() & obj!=null & !obj.exists()) - fos=new FileOutputStream(file); - } - catch(Exception e) - { - // File could not be opened for write, or Security Exception - // was thrown. If someone else created the file before we could - // open it, that's probably a threading conflict and we don't - // bother reporting it. - if(!file.exists()) - { - logger.error("openUniqueFile: unexpected "+e); - } - } - } - if(fos==null) - logger.error("openUniqueFile: Failed "+max+"attempts."); - else - gf=new GeneratedFile(file,fos,className); - return gf; - } - - public void undeclareBean (BSFDeclaredBean bean) throws BSFException {} -} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTEngine.java b/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTEngine.java deleted file mode 100644 index 893ab62c3..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTEngine.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.engines.xslt; - -import java.io.File; -import java.io.Reader; -import java.io.StringReader; -import java.net.URL; -import java.util.Vector; - -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMResult; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamSource; - -import com.volmit.iris.util.bsf.BSFDeclaredBean; -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; -import com.volmit.iris.util.bsf.util.BSFEngineImpl; -import com.volmit.iris.util.bsf.util.BSFFunctions; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.xpath.objects.XObject; -import org.w3c.dom.Node; - -/** - * Xerces XSLT interface to BSF. Requires Xalan and Xerces from Apache. - * - * This integration uses the BSF registry to pass in any src document - * and stylesheet base URI that the user may wish to set. - * - * @author Sanjiva Weerawarana - * @author Sam Ruby - * - * Re-implemented for the Xalan 2 codebase - * - * @author Victor J. Orlikowski - */ -public class XSLTEngine extends BSFEngineImpl { - TransformerFactory tFactory; - Transformer transformer; - - Log logger = LogFactory.getLog(this.getClass().getName()); - - /** - * call the named method of the given object. - */ - public Object call (Object object, String method, Object[] args) - throws BSFException { - throw new BSFException (BSFException.REASON_UNSUPPORTED_FEATURE, - "BSF:XSLTEngine can't call methods"); - } - - /** - * Declare a bean by setting it as a parameter - */ - public void declareBean (BSFDeclaredBean bean) throws BSFException { - transformer.setParameter (bean.name, new XObject (bean.bean)); - } - - /** - * Evaluate an expression. In this case, an expression is assumed - * to be a stylesheet of the template style (see the XSLT spec). - */ - public Object eval (String source, int lineNo, int columnNo, - Object oscript) throws BSFException { - // get the style base URI (the place from where Xerces XSLT will - // look for imported/included files and referenced docs): if a - // bean named "xslt:styleBaseURI" is registered, then cvt it - // to a string and use that. Otherwise use ".", which means the - // base is the directory where the process is running from - Object sbObj = mgr.lookupBean ("xslt:styleBaseURI"); - String styleBaseURI = (sbObj == null) ? "." : sbObj.toString (); - - // Locate the stylesheet. - StreamSource styleSource; - - styleSource = - new StreamSource(new StringReader(oscript.toString ())); - styleSource.setSystemId(styleBaseURI); - - try { - transformer = tFactory.newTransformer(styleSource); - } catch (Exception e) { - logger.error("Exception from Xerces XSLT:", e); - throw new BSFException (BSFException.REASON_EXECUTION_ERROR, - "Exception from Xerces XSLT: " + e, e); - } - - // get the src to work on: if a bean named "xslt:src" is registered - // and its a Node, then use it as the source. If its not a Node, then - // if its a URL parse it, if not treat it as a file and make a URL and - // parse it and go. If no xslt:src is found, use an empty document - // (stylesheet is treated as a literal result element stylesheet) - Object srcObj = mgr.lookupBean ("xslt:src"); - Object xis = null; - if (srcObj != null) { - if (srcObj instanceof Node) { - xis = new DOMSource((Node)srcObj); - } else { - try { - String mesg = "as anything"; - if (srcObj instanceof Reader) { - xis = new StreamSource ((Reader) srcObj); - mesg = "as a Reader"; - } else if (srcObj instanceof File) { - xis = new StreamSource ((File) srcObj); - mesg = "as a file"; - } else { - String srcObjstr=srcObj.toString(); - xis = new StreamSource (new StringReader(srcObjstr)); - if (srcObj instanceof URL) { - mesg = "as a URL"; - } else { - ((StreamSource) xis).setPublicId (srcObjstr); - mesg = "as an XML string"; - } - } - - if (xis == null) { - throw new Exception ("Unable to get input from '" + - srcObj + "' " + mesg); - } - } catch (Exception e) { - throw new BSFException (BSFException.REASON_EXECUTION_ERROR, - "BSF:XSLTEngine: unable to get " + - "input from '" + srcObj + "' as XML", e); - } - } - } else { - // create an empty document - real src must come into the - // stylesheet using "doc(...)" [see XSLT spec] or the stylesheet - // must be of literal result element type - xis = new StreamSource(); - } - - // set all declared beans as parameters. - for (int i = 0; i < declaredBeans.size (); i++) { - BSFDeclaredBean b = (BSFDeclaredBean) declaredBeans.elementAt (i); - transformer.setParameter (b.name, new XObject (b.bean)); - } - - // declare a "bsf" parameter which is the BSF handle so that - // the script can do BSF stuff if it wants to - transformer.setParameter ("bsf", - new XObject (new BSFFunctions (mgr, this))); - - // do it - try { - DOMResult result = new DOMResult(); - transformer.transform ((StreamSource) xis, result); - return new XSLTResultNode (result.getNode()); - } catch (Exception e) { - throw new BSFException (BSFException.REASON_EXECUTION_ERROR, - "exception while eval'ing XSLT script" + e, e); - } - } - - /** - * Initialize the engine. - */ - public void initialize (BSFManager mgr, String lang, - Vector declaredBeans) throws BSFException { - super.initialize (mgr, lang, declaredBeans); - - tFactory = TransformerFactory.newInstance(); - } - - /** - * Undeclare a bean by setting he parameter represeting it to null - */ - public void undeclareBean (BSFDeclaredBean bean) throws BSFException { - // Cannot clear only one parameter in Xalan 2, so we set it to null - if ((transformer.getParameter (bean.name)) != null) { - transformer.setParameter (bean.name, null); - } - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTResultNode.java b/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTResultNode.java deleted file mode 100644 index 612ded3f7..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/engines/xslt/XSLTResultNode.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.engines.xslt; - -import org.w3c.dom.Node; - -public class XSLTResultNode -{ - Node node; - - public XSLTResultNode(Node node) - { - this.node = node; - } - public Node getNode() - { - return node; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/BSFClassLoader.java b/src/main/java/com/volmit/iris/util/bsf/util/BSFClassLoader.java deleted file mode 100644 index 557838e8d..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/BSFClassLoader.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.io.File; -import java.io.FileInputStream; -import java.util.Hashtable; - -/** - * This class loader knows to load a class from the tempDir dir - * of the environment of the given manager. - * - * @author Sanjiva Weerawarana - */ -class BSFClassLoader extends ClassLoader { - Hashtable cache = new Hashtable (); - String tempDir = "."; - - // note the non-public constructor - this is only avail within - // this package. - BSFClassLoader () { - } - public synchronized Class loadClass (String name, boolean resolve) - throws ClassNotFoundException { - Class c = (Class) cache.get (name); - if (c == null) { - // is it a system class - try { - c = findSystemClass (name); - cache.put (name, c); - return c; - } catch (ClassNotFoundException e) { - // nope - } - try { - byte[] data = loadClassData (name); - c = defineClass (name, data, 0, data.length); - cache.put (name, c); - } catch (Exception e) { - e.printStackTrace (); - throw new ClassNotFoundException ("unable to resolve class '" + - name + "'"); - } - } - if (resolve) - resolveClass (c); - return c; - } - private byte[] loadClassData (String name) throws Exception { - String fileName = tempDir + File.separatorChar + name + ".class"; - FileInputStream fi = new FileInputStream (fileName); - byte[] data = new byte[fi.available ()]; - fi.read (data); - fi.close(); - return data; - } - public void setTempDir (String tempDir) { - this.tempDir = tempDir; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/BSFEngineImpl.java b/src/main/java/com/volmit/iris/util/bsf/util/BSFEngineImpl.java deleted file mode 100644 index d38dead04..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/BSFEngineImpl.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.beans.PropertyChangeEvent; -import java.util.Vector; - -import com.volmit.iris.util.bsf.BSFDeclaredBean; -import com.volmit.iris.util.bsf.BSFEngine; -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; - -/** - * This is a base implementation of the BSFEngine interface which - * engine implementations may choose to extend to get the basic - * methods of the interface implemented. - *

- * - * @author Sanjiva Weerawarana - * @author Olivier Gruber (added original debugging support) - */ - -public abstract class BSFEngineImpl implements BSFEngine { - - protected BSFManager mgr; // my manager - protected String lang; // my language string - protected Vector declaredBeans; // BSFDeclaredBeans - protected String classPath; - protected String tempDir; - protected ClassLoader classLoader; - - /** - * Default impl of apply - calls eval ignoring parameters and returns - * the result. - */ - public Object apply(String source, int lineNo, int columnNo, - Object funcBody, Vector paramNames, Vector arguments) - throws BSFException { - return eval(source, lineNo, columnNo, funcBody); - } - - /** - * Default impl of compileApply - calls compileExpr ignoring parameters. - */ - public void compileApply(String source, int lineNo, int columnNo, - Object funcBody, Vector paramNames, - Vector arguments, CodeBuffer cb) - throws BSFException { - compileExpr(source, lineNo, columnNo, funcBody, cb); - } - - /** - * Default impl of compileExpr - generates code that'll create a new - * manager, evaluate the expression, and return the value. - */ - public void compileExpr(String source, int lineNo, int columnNo, - Object expr, CodeBuffer cb) throws BSFException { - ObjInfo bsfInfo = cb.getSymbol("bsf"); - - if (bsfInfo == null) { - bsfInfo = new ObjInfo(BSFManager.class, "bsf"); - cb.addFieldDeclaration("com.volmit.iris.util.bsf.BSFManager bsf = " + - "new com.volmit.iris.util.bsf.BSFManager();"); - cb.putSymbol("bsf", bsfInfo); - } - - String evalString = bsfInfo.objName + ".eval(\"" + lang + "\", "; - evalString += "request.getRequestURI(), " + lineNo + ", " + columnNo; - evalString += "," + StringUtils.lineSeparator; - evalString += StringUtils.getSafeString(expr.toString()) + ")"; - - ObjInfo oldRet = cb.getFinalServiceMethodStatement(); - - if (oldRet != null && oldRet.isExecutable()) { - cb.addServiceMethodStatement(oldRet.objName + ";"); - } - - cb.setFinalServiceMethodStatement(new ObjInfo(Object.class, - evalString)); - - cb.addServiceMethodException("com.volmit.iris.util.bsf.BSFException"); - } - - /** - * Default impl of compileScript - generates code that'll create a new - * manager, and execute the script. - */ - public void compileScript(String source, int lineNo, int columnNo, - Object script, CodeBuffer cb) - throws BSFException { - ObjInfo bsfInfo = cb.getSymbol("bsf"); - - if (bsfInfo == null) { - bsfInfo = new ObjInfo(BSFManager.class, "bsf"); - cb.addFieldDeclaration("com.volmit.iris.util.bsf.BSFManager bsf = " + - "new com.volmit.iris.util.bsf.BSFManager();"); - cb.putSymbol("bsf", bsfInfo); - } - - String execString = bsfInfo.objName + ".exec(\"" + lang + "\", "; - execString += "request.getRequestURI(), " + lineNo + ", " + columnNo; - execString += "," + StringUtils.lineSeparator; - execString += StringUtils.getSafeString(script.toString()) + ")"; - - ObjInfo oldRet = cb.getFinalServiceMethodStatement(); - - if (oldRet != null && oldRet.isExecutable()) { - cb.addServiceMethodStatement(oldRet.objName + ";"); - } - - cb.setFinalServiceMethodStatement(new ObjInfo(void.class, execString)); - - cb.addServiceMethodException("com.volmit.iris.util.bsf.BSFException"); - } - - public void declareBean(BSFDeclaredBean bean) throws BSFException { - throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE, - "language " + lang + - " does not support declareBean(...)."); - } - - /** - * Default impl of execute - calls eval and ignores the result. - */ - public void exec(String source, int lineNo, int columnNo, Object script) - throws BSFException { - eval(source, lineNo, columnNo, script); - } - - /** - * Default impl of interactive execution - calls eval and ignores the result. - */ - public void iexec(String source, int lineNo, int columnNo, Object script) - throws BSFException { - eval(source, lineNo, columnNo, script); - } - - /** - * initialize the engine; called right after construction by - * the manager. Declared beans are simply kept in a vector and - * that's it. Subclasses must do whatever they want with it. - */ - public void initialize(BSFManager mgr, String lang, Vector declaredBeans) - throws BSFException { - - this.mgr = mgr; - this.lang = lang; - this.declaredBeans = declaredBeans; - - // initialize my properties from those of the manager. It'll send - // propagate change events to me - this.classPath = mgr.getClassPath(); - this.tempDir = mgr.getTempDir(); - this.classLoader = mgr.getClassLoader(); - } - - /** - * Receive property change events from the manager and update my fields - * as needed. - * - * @param e PropertyChange event with the change data - */ - public void propertyChange(PropertyChangeEvent e) { - String name = e.getPropertyName(); - Object value = e.getNewValue(); - - if (name.equals("classPath")) { - classPath = (String) value; - } - else if (name.equals("tempDir")) { - tempDir = (String) value; - } - else if (name.equals("classLoader")) { - classLoader = (ClassLoader) value; - } - } - - public void terminate() { - mgr = null; - declaredBeans = null; - classLoader = null; - } - - public void undeclareBean(BSFDeclaredBean bean) throws BSFException { - throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE, - "language " + lang + - " does not support undeclareBean(...)."); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessor.java b/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessor.java deleted file mode 100644 index b59baca29..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessor.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import com.volmit.iris.util.bsf.BSFEngine; -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; -import com.volmit.iris.util.bsf.util.event.EventProcessor; - -/** - * This is used to support binding scripts to be run when an event - * occurs. - * - * @author Sanjiva Weerawarana - */ -public class BSFEventProcessor implements EventProcessor { - BSFEngine engine; - BSFManager manager; - String filter; - String source; - int lineNo; - int columnNo; - Object script; - - /** - * Package-protected constructor makes this class unavailable for - * public use. - */ - BSFEventProcessor (BSFEngine engine, BSFManager manager, String filter, - String source, int lineNo, int columnNo, Object script) - throws BSFException { - this.engine = engine; - this.manager = manager; - this.filter = filter; - this.source = source; - this.lineNo = lineNo; - this.columnNo = columnNo; - this.script = script; - } - ////////////////////////////////////////////////////////////////////////// - // - // event is delegated to me by the adapters using this. inFilter is - // in general the name of the method via which the event was received - // at the adapter. For prop/veto change events, inFilter is the name - // of the property. In any case, in the event processor, I only forward - // those events if for which the filters match (if one is specified). - - public void processEvent (String inFilter, Object[] evtInfo) { - try { - processExceptionableEvent (inFilter, evtInfo); - } catch (RuntimeException re) { - // rethrow this .. I don't want to intercept run-time stuff - // that can in fact occur legit - throw re; - } catch (Exception e) { - // should not occur - System.err.println ("BSFError: non-exceptionable event delivery " + - "threw exception (that's not nice): " + e); - e.printStackTrace (); - } - } - ////////////////////////////////////////////////////////////////////////// - // - // same as above, but used when the method event method may generate - // an exception which must go all the way back to the source (as in - // the vetoableChange case) - - public void processExceptionableEvent (String inFilter, Object[] evtInfo) throws Exception - { - if ((filter != null) && !filter.equals (inFilter)) { - // ignore this event - return; - } - - // run the script - engine.exec (source, lineNo, columnNo, script); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessorReturningEventInfos.java b/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessorReturningEventInfos.java deleted file mode 100644 index a8aac16b1..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/BSFEventProcessorReturningEventInfos.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * This software consists of voluntary contributions made by many individuals - * on behalf of the Apache Software Foundation and was originally created by - * Sanjiva Weerawarana and others at International Business Machines - * Corporation. For more information on the Apache Software Foundation, - * please see . - */ - -package com.volmit.iris.util.bsf.util; - -import java.util.Vector; - -import com.volmit.iris.util.bsf.BSFEngine; -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; -import com.volmit.iris.util.bsf.util.event.EventProcessor; - -/* - * Copyright (C) 2001-2006 Rony G. Flatscher - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - * - */ - -/** - * - * This is used to support binding scripts to be run when an event occurs, - * forwarding the arguments supplied to the event listener. It is an adapted - * version of com.volmit.iris.util.bsf.util.BSFEventProcessor. - * - * @author Rony G. Flatscher, but most of the code copied from - * com.volmit.iris.util.bsf.util.BSFEventProcessor by Sanjiva Weerawarana - */ -public class BSFEventProcessorReturningEventInfos implements EventProcessor { - BSFEngine engine; - - BSFManager manager; - - String filter; - - String source; - - int lineNo; - - int columnNo; - - Object script; - - Object dataFromScriptingEngine; // ---rgf, 2006-02-24: data coming from the - // script engine, could be - - // e.g. an object reference to forward event with received arguments to - - /** - * Package-protected constructor makes this class unavailable for public - * use. - * - * @param dataFromScriptingEngine - * this contains any object supplied by the scripting engine and - * gets sent back with the supplied script. This could be used - * e.g. for indicating which scripting engine object should be - * ultimately informed of the event occurrence. - */ - BSFEventProcessorReturningEventInfos(BSFEngine engine, BSFManager manager, - String filter, String source, int lineNo, int columnNo, - Object script, Object dataFromScriptingEngine) throws BSFException { - this.engine = engine; - this.manager = manager; - this.filter = filter; - this.source = source; - this.lineNo = lineNo; - this.columnNo = columnNo; - this.script = script; - this.dataFromScriptingEngine = dataFromScriptingEngine; - } - - // //////////////////////////////////////////////////////////////////////// - // - // event is delegated to me by the adapters using this. inFilter is - // in general the name of the method via which the event was received - // at the adapter. For prop/veto change events, inFilter is the name - // of the property. In any case, in the event processor, I only forward - // those events if for which the filters match (if one is specified). - - public void processEvent(String inFilter, Object[] evtInfo) { - try { - processExceptionableEvent(inFilter, evtInfo); - } catch (RuntimeException re) { - // rethrow this .. I don't want to intercept run-time stuff - // that can in fact occur legit - throw re; - } catch (Exception e) { - // should not occur - System.err.println("BSFError: non-exceptionable event delivery " - + "threw exception (that's not nice): " + e); - e.printStackTrace(); - } - } - - // //////////////////////////////////////////////////////////////////////// - // - // same as above, but used when the method event method may generate - // an exception which must go all the way back to the source (as in - // the vetoableChange case) - - public void processExceptionableEvent(String inFilter, Object[] evtInfo) - throws Exception { - - // System.err.println(this+": inFilter=["+inFilter+"], - // filter=["+filter+"]"); - if ((filter != null) && !filter.equals(inFilter)) { - // ignore this event - return; - } - - // run the script - // engine.exec (source, lineNo, columnNo, script); - - // create the parameter vectors for engine.apply() - Vector paramNames = new Vector(), paramValues = new Vector(); - - // parameter # 1 - // supply the parameters as an array object as sent to the event object - // listener - // (usually the first entry is the sent event object) - paramNames.add("eventParameters"); - paramValues.add(evtInfo); - - // parameter # 2 - // supply the data object received from the scripting engine to be sent - // with the event - paramNames.add("dataFromScriptingEngine"); - paramValues.add(this.dataFromScriptingEngine); // can be null as well - - // parameter # 3 - // event filter in place - paramNames.add("inFilter"); - paramValues.add(inFilter); // event name that has occurred - - // parameter # 4 - // event filter in place - paramNames.add("eventFilter"); - paramValues.add(this.filter); // can be null as well - - // parameter # 5 - // BSF manager instance (e.g. allows access to its registry) - paramNames.add("BSFManager"); - paramValues.add(this.manager); - - engine.apply(source, lineNo, columnNo, this.script, paramNames, - paramValues); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/BSFFunctions.java b/src/main/java/com/volmit/iris/util/bsf/util/BSFFunctions.java deleted file mode 100644 index 08ded56ec..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/BSFFunctions.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import com.volmit.iris.util.bsf.BSFEngine; -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; - -/** - * This is a utility that engine implementors may use as the Java - * object they expose in the scripting language as "bsf". This has - * essentially a subset of the methods in BSFManager plus some - * stuff from the utils. Currently used by Javascript (Rhino) & BML. - * - * @author Sanjiva Weerawarana - */ -public class BSFFunctions { - BSFManager mgr; - BSFEngine engine; - - public BSFFunctions (BSFManager mgr, BSFEngine engine) { - this.mgr = mgr; - this.engine = engine; - } - public void addEventListener (Object src, String eventSetName, - String filter, Object script) - throws BSFException { - EngineUtils.addEventListener (src, eventSetName, filter, engine, - mgr, "", 0, 0, script); - } - public Object lookupBean (String name) { - return mgr.lookupBean (name); - } - public void registerBean (String name, Object bean) { - mgr.registerBean (name, bean); - } - public void unregisterBean (String name) { - mgr.unregisterBean (name); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/Bean.java b/src/main/java/com/volmit/iris/util/bsf/util/Bean.java deleted file mode 100644 index d6fdd752f..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/Bean.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -/** - * A Bean is the class used to represent a bean: it holds a - * type and a value. This is needed because otherwise we can't represent - * the types of null-valued beans (or primitives) correctly. This was - * originally in the BML player. - * - * @author Sanjiva Weerawarana - */ -public class Bean { - // type of this bean - public Class type; - - // its current value (mebbe null) - public Object value; - - public Bean (Class type, Object value) { - this.type = type; - this.value = value; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/CodeBuffer.java b/src/main/java/com/volmit/iris/util/bsf/util/CodeBuffer.java deleted file mode 100644 index e38a12582..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/CodeBuffer.java +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; -import java.util.Hashtable; -import java.util.Stack; -import java.util.Vector; - -import com.volmit.iris.util.bsf.util.cf.CodeFormatter; - -/** - * A CodeBuffer object is used as a code repository for generated Java code. - * It provides buffers which correspond to the various sections of a Java class. - * - * @author Matthew J. Duftler - */ -public class CodeBuffer -{ - private StringWriter fieldDeclSW = new StringWriter(), - methodDeclSW = new StringWriter(), - initializerSW = new StringWriter(), - constructorSW = new StringWriter(), - serviceMethodSW = new StringWriter(); - - private PrintWriter fieldDeclPW = new PrintWriter(fieldDeclSW), - methodDeclPW = new PrintWriter(methodDeclSW), - initializerPW = new PrintWriter(initializerSW), - constructorPW = new PrintWriter(constructorSW), - serviceMethodPW = new PrintWriter(serviceMethodSW); - - private Stack symbolTableStack = new Stack(); - private Hashtable symbolTable = new Hashtable(), - usedSymbolIndices = new Hashtable(); - - private ObjInfo finalStatementInfo; - private CodeBuffer parent; - - - { - symbolTableStack.push(symbolTable); - } - - // New stuff... - private Vector imports = new Vector(), - constructorArguments = new Vector(), - constructorExceptions = new Vector(), - serviceMethodExceptions = new Vector(), - implementsVector = new Vector(); - private String packageName = null, - className = "Test", - serviceMethodName = "exec", - extendsName = null; - private Class serviceMethodReturnType = void.class; - - public CodeBuffer() - { - } - public CodeBuffer(CodeBuffer parent) - { - this.parent = parent; - } - public void addConstructorArgument(ObjInfo arg) - { - constructorArguments.addElement(arg); - } - public void addConstructorException(String exceptionName) - { - if (!constructorExceptions.contains(exceptionName)) - { - constructorExceptions.addElement(exceptionName); - } - } - public void addConstructorStatement(String statement) - { - constructorPW.println(statement); - } - public void addFieldDeclaration(String statement) - { - fieldDeclPW.println(statement); - } - public void addImplements(String importName) - { - if (!implementsVector.contains(importName)) - { - implementsVector.addElement(importName); - } - } - public void addImport(String importName) - { - if (!imports.contains(importName)) - { - imports.addElement(importName); - } - } - public void addInitializerStatement(String statement) - { - initializerPW.println(statement); - } - public void addMethodDeclaration(String statement) - { - methodDeclPW.println(statement); - } - public void addServiceMethodException(String exceptionName) - { - if (!serviceMethodExceptions.contains(exceptionName)) - { - serviceMethodExceptions.addElement(exceptionName); - } - } - public void addServiceMethodStatement(String statement) - { - serviceMethodPW.println(statement); - } - // Used internally by merge(...). - private void appendIfNecessary(PrintWriter pw, StringBuffer buf) - { - if (buf.length() > 0) - { - pw.print(buf.toString()); - } - } - public String buildNewSymbol(String prefix) - { - Integer nextNum = getSymbolIndex(prefix); - - if (nextNum == null) - { - nextNum = new Integer(0); - } - - int iNextNum = nextNum.intValue(); - String symbol = prefix + "_" + iNextNum; - - while (getSymbol(symbol) != null) - { - iNextNum++; - symbol = prefix + "_" + iNextNum; - } - - putSymbolIndex(prefix, new Integer(iNextNum + 1)); - - return symbol; - } - public void clearSymbolTable() - { - symbolTable = new Hashtable(); - symbolTableStack = new Stack(); - symbolTableStack.push(symbolTable); - - usedSymbolIndices = new Hashtable(); - } - public String getClassName() - { - return className; - } - public Vector getConstructorArguments() - { - return constructorArguments; - } - public StringBuffer getConstructorBuffer() - { - constructorPW.flush(); - - return constructorSW.getBuffer(); - } - public Vector getConstructorExceptions() - { - return constructorExceptions; - } - public String getExtends() - { - return extendsName; - } - public StringBuffer getFieldBuffer() - { - fieldDeclPW.flush(); - - return fieldDeclSW.getBuffer(); - } - public ObjInfo getFinalServiceMethodStatement() - { - return finalStatementInfo; - } - public Vector getImplements() - { - return implementsVector; - } - public Vector getImports() - { - return imports; - } - public StringBuffer getInitializerBuffer() - { - initializerPW.flush(); - - return initializerSW.getBuffer(); - } - public StringBuffer getMethodBuffer() - { - methodDeclPW.flush(); - - return methodDeclSW.getBuffer(); - } - public String getPackageName() - { - return packageName; - } - public StringBuffer getServiceMethodBuffer() - { - serviceMethodPW.flush(); - - return serviceMethodSW.getBuffer(); - } - public Vector getServiceMethodExceptions() - { - return serviceMethodExceptions; - } - public String getServiceMethodName() - { - return serviceMethodName; - } - public Class getServiceMethodReturnType() - { - if (finalStatementInfo != null) - { - return finalStatementInfo.objClass; - } - else if (serviceMethodReturnType != null) - { - return serviceMethodReturnType; - } - else - { - return void.class; - } - } - public ObjInfo getSymbol(String symbol) - { - ObjInfo ret = (ObjInfo)symbolTable.get(symbol); - - if (ret == null && parent != null) - ret = parent.getSymbol(symbol); - - return ret; - } - Integer getSymbolIndex(String prefix) - { - if (parent != null) - { - return parent.getSymbolIndex(prefix); - } - else - { - return (Integer)usedSymbolIndices.get(prefix); - } - } - public Hashtable getSymbolTable() - { - return symbolTable; - } - public void merge(CodeBuffer otherCB) - { - Vector otherImports = otherCB.getImports(); - - for (int i = 0; i < otherImports.size(); i++) - { - addImport((String)otherImports.elementAt(i)); - } - - appendIfNecessary(fieldDeclPW, otherCB.getFieldBuffer()); - appendIfNecessary(methodDeclPW, otherCB.getMethodBuffer()); - appendIfNecessary(initializerPW, otherCB.getInitializerBuffer()); - appendIfNecessary(constructorPW, otherCB.getConstructorBuffer()); - appendIfNecessary(serviceMethodPW, otherCB.getServiceMethodBuffer()); - - ObjInfo oldRet = getFinalServiceMethodStatement(); - - if (oldRet != null && oldRet.isExecutable()) - { - addServiceMethodStatement(oldRet.objName + ";"); - } - - setFinalServiceMethodStatement(otherCB.getFinalServiceMethodStatement()); - } - public void popSymbolTable() - { - symbolTableStack.pop(); - symbolTable = (Hashtable)symbolTableStack.peek(); - } - public void print(PrintWriter out, boolean formatOutput) - { - if (formatOutput) - { - new CodeFormatter().formatCode(new StringReader(toString()), out); - } - else - { - out.print(toString()); - } - - out.flush(); - } - public void pushSymbolTable() - { - symbolTable = (Hashtable)symbolTableStack.push(new ScriptSymbolTable(symbolTable)); - } - public void putSymbol(String symbol, ObjInfo obj) - { - symbolTable.put(symbol, obj); - } - void putSymbolIndex(String prefix, Integer index) - { - if (parent != null) - { - parent.putSymbolIndex(prefix, index); - } - else - { - usedSymbolIndices.put(prefix, index); - } - } - public void setClassName(String className) - { - this.className = className; - } - public void setExtends(String extendsName) - { - this.extendsName = extendsName; - } - public void setFinalServiceMethodStatement(ObjInfo finalStatementInfo) - { - this.finalStatementInfo = finalStatementInfo; - } - public void setPackageName(String packageName) - { - this.packageName = packageName; - } - public void setServiceMethodName(String serviceMethodName) - { - this.serviceMethodName = serviceMethodName; - } - public void setServiceMethodReturnType(Class serviceMethodReturnType) - { - this.serviceMethodReturnType = serviceMethodReturnType; - } - public void setSymbolTable(Hashtable symbolTable) - { - this.symbolTable = symbolTable; - } - public boolean symbolTableIsStacked() - { - return (symbolTable instanceof ScriptSymbolTable); - } - public String toString() - { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - ObjInfo ret = finalStatementInfo; - - if (packageName != null && !packageName.equals("")) - { - pw.println("package " + packageName + ";"); - pw.println(); - } - - if (imports.size() > 0) - { - for (int i = 0; i < imports.size(); i++) - { - pw.println("import " + imports.elementAt(i) + ";"); - } - - pw.println(); - } - - pw.println("public class " + className + - (extendsName != null && !extendsName.equals("") - ? " extends " + extendsName - : "") + - (implementsVector.size() > 0 - ? " implements " + - StringUtils.getCommaListFromVector(implementsVector) - : "") - ); - pw.println("{"); - - pw.print(getFieldBuffer().toString()); - - StringBuffer buf = getInitializerBuffer(); - - if (buf.length() > 0) - { - pw.println(); - pw.println("{"); - pw.print(buf.toString()); - pw.println("}"); - } - - buf = getConstructorBuffer(); - - if (buf.length() > 0) - { - pw.println(); - pw.println("public " + className + "(" + - (constructorArguments.size() > 0 - ? StringUtils.getCommaListFromVector(constructorArguments) - : "" - ) + ")" + - (constructorExceptions.size() > 0 - ? " throws " + - StringUtils.getCommaListFromVector(constructorExceptions) - : "" - ) - ); - pw.println("{"); - pw.print(buf.toString()); - pw.println("}"); - } - - buf = getServiceMethodBuffer(); - - if (buf.length() > 0 || ret != null) - { - pw.println(); - pw.println("public " + - StringUtils.getClassName(getServiceMethodReturnType()) + " " + - serviceMethodName + "()" + - (serviceMethodExceptions.size() > 0 - ? " throws " + - StringUtils.getCommaListFromVector(serviceMethodExceptions) - : "" - ) - ); - pw.println("{"); - - pw.print(buf.toString()); - - if (ret != null) - { - if (ret.isValueReturning()) - { - pw.println(); - pw.println("return " + ret.objName + ";"); - } - else if (ret.isExecutable()) - { - pw.println(ret.objName + ";"); - } - } - - pw.println("}"); - } - - pw.print(getMethodBuffer().toString()); - - pw.println("}"); - - pw.flush(); - - return sw.toString(); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/EngineUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/EngineUtils.java deleted file mode 100644 index 90e32f73f..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/EngineUtils.java +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -import com.volmit.iris.util.bsf.BSFEngine; -import com.volmit.iris.util.bsf.BSFException; -import com.volmit.iris.util.bsf.BSFManager; - -/** - * This class contains utilities that language integrators can use - * when implementing the BSFEngine interface. - * - * @author Sanjiva Weerawarana - * @author Sam Ruby - * @author Rony G. Flatscher (added addEventListenerReturningEventInfos) - */ -public class EngineUtils { - // the BSF class loader that knows how to load from the a specific - // temp directory - static BSFClassLoader bsfCL; - - // ---rgf, 2003-02-13, determine whether changing accessibility of Methods is possible - static boolean bMethodHasSetAccessible=false; - static { - Class mc=Method.class; // get the "Method" class object - Class arg[]={boolean.class}; // define an array with the primitive "boolean" pseudo class object - try { - mc.getMethod("setAccessible", arg ); // is this method available? - bMethodHasSetAccessible=true; // no exception, hence method exists - } - catch (Exception e) - { - bMethodHasSetAccessible=false;// exception occurred, hence method does not exist - } - } - - - /** - * Add a script as a listener to some event coming out of an object. The - * first two args identify the src of the event and the event set - * and the rest identify the script which should be run when the event - * fires. - * - * @param bean event source - * @param eventSetName name of event set from event src to bind to - * @param filter filter for events - * @param engine BSFEngine which can run this script - * @param manager BSFManager of the above engine - * @param source (context info) the source of this expression - * (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param script the script to execute when the event occurs - * - * @exception BSFException if anything goes wrong while running the script - */ - public static void addEventListener (Object bean, String eventSetName, - String filter, BSFEngine engine, - BSFManager manager, String source, - int lineNo, int columnNo, - Object script) throws BSFException { - BSFEventProcessor ep = new BSFEventProcessor (engine, manager, filter, - source, lineNo, columnNo, - script); - - try { - ReflectionUtils.addEventListener (bean, eventSetName, ep); - } catch (Exception e) { - e.printStackTrace (); - throw new BSFException (BSFException.REASON_OTHER_ERROR, - "ouch while adding event listener: " - + e, e); - } - } - - - /** - * Add a script as a listener to some event coming out of an object. The - * first two args identify the src of the event and the event set - * and the rest identify the script which should be run when the event - * fires. The processing will use the engine's apply() method. - * - * @param bean event source - * @param eventSetName name of event set from event src to bind to - * @param filter filter for events - * @param engine BSFEngine which can run this script - * @param manager BSFManager of the above engine - * @param source (context info) the source of this expression (e.g., filename) - * @param lineNo (context info) the line number in source for expr - * @param columnNo (context info) the column number in source for expr - * @param script the script to execute when the event occurs - * @param dataFromScriptingEngine - * this contains any object supplied by the scripting engine and gets sent - * back with the supplied script, if the event occurs. - * This could be used e.g. for indicating to the scripting engine which - * scripting engine object/routine/function/procedure - * should be ultimately informed of the event occurrence. - * - * @exception BSFException if anything goes wrong while running the script - */ - public static void addEventListenerReturningEventInfos ( Object bean, - String eventSetName, - String filter, - BSFEngine engine, - BSFManager manager, - String source, - int lineNo, - int columnNo, - Object script, - Object dataFromScriptingEngine - ) throws BSFException - { - BSFEventProcessorReturningEventInfos ep = - new BSFEventProcessorReturningEventInfos (engine, - manager, - filter, - source, - lineNo, - columnNo, - script, - dataFromScriptingEngine - ); - - try { - ReflectionUtils.addEventListener (bean, eventSetName, ep); - } catch (Exception e) { - e.printStackTrace (); - throw new BSFException (BSFException.REASON_OTHER_ERROR, - "ouch while adding event listener: " - + e, e); - } - } - - /** - * Finds and invokes a method with the given signature on the given - * bean. The signature of the method that's invoked is first taken - * as the types of the args, but if that fails, this tries to convert - * any primitive wrapper type args to their primitive counterparts - * to see whether a method exists that way. If it does, done. - * - * @param bean the object on which to invoke the method - * @param methodName name of the method - * @param args arguments to be given to the method - * - * @return the result of invoking the method, if any - * - * @exception BSFException if something goes wrong - */ - public static Object callBeanMethod (Object bean, String methodName, - Object[] args) throws BSFException { - Class[] argTypes = null; - // determine arg types. note that a null argtype - // matches any object type - - if (args != null) { - argTypes = new Class[args.length]; - for (int i = 0; i < args.length; i++) { - argTypes[i] = (args[i] == null) ? null : args[i].getClass (); - } - } - - // we want to allow a static call to occur on an object, similar - // to what Java allows. So isStaticOnly is set to false. - boolean isStaticOnly = false; - Class beanClass = (bean instanceof Class) ? (Class)bean : - bean.getClass (); - - // now try to call method with the right signature - try { - Method m; - try { - m = MethodUtils.getMethod (beanClass, methodName, argTypes, - isStaticOnly); - } catch (NoSuchMethodException e) { - // ok, so that didn't work - now try converting any primitive - // wrapper types to their primitive counterparts - try { - // if args is null the NullPointerException will get caught - // below and the right thing'll happen .. ugly but works - for (int i = 0; i < args.length; i++) { - if (args[i] instanceof Number) - { - if (args[i] instanceof Byte) argTypes[i] = byte.class; - else if (args[i] instanceof Integer) argTypes[i] = int.class; - else if (args[i] instanceof Long) argTypes[i] = long.class; - else if (args[i] instanceof Float) argTypes[i] = float.class; - else if (args[i] instanceof Double ) argTypes[i] = double.class; - else if (args[i] instanceof Short ) argTypes[i] = short.class; - } - else if (args[i] instanceof Boolean) argTypes[i] = boolean.class; - else if (args[i] instanceof Character) argTypes[i] = char.class; - } - - m = MethodUtils.getMethod (beanClass, methodName, argTypes, - isStaticOnly); - } catch (Exception e2) { - // throw the original - throw e; - } - } - - // call it, and return the result - try { - return m.invoke (bean, args); - } - catch (Exception e) // 2003-02-23, --rgf, maybe an IllegalAccessException? - { - if (e instanceof IllegalAccessException && - bMethodHasSetAccessible && - Modifier.isPublic(m.getModifiers()) ) // if a public method allow access to it - { - m.setAccessible(true); // allow unconditional access to method - return m.invoke (bean, args); - } - // re-throw the exception - throw e; - } - - } catch (Exception e) { - // something went wrong while invoking method - Throwable t = (e instanceof InvocationTargetException) ? - ((InvocationTargetException)e).getTargetException () : - null; - throw new BSFException (BSFException.REASON_OTHER_ERROR, - "method invocation failed: " + e + - ((t==null) ? "" : - (" target exception: " + t)), t); - } - } - - /** - * Creates a new bean. The signature of the constructor that's invoked - * is first taken as the types of the args, but if that fails, this tries - * to convert any primitive wrapper type args to their primitive - * counterparts to see whether a method exists that way. If it does, done. - * - * @param className fully qualified name of class to instantiate - * @param args array of constructor args (or null if none) - * - * @return the created bean - * - * @exception BSFException if something goes wrong (@see - * org.apache.cs.util.MethodUtils for the real - * exceptions that can occur). - */ - public static Object createBean (String className, Object args[]) - throws BSFException { - Bean obj; - Class[] argTypes = null; - - if (args != null) { - argTypes = new Class[args.length]; - for (int i = 0; i < args.length; i++) { - argTypes[i] = (args[i] != null) ? args[i].getClass () : null; - } - } - - try { - try { - obj = ReflectionUtils.createBean (null, className, - argTypes, args); - return obj.value; - } catch (NoSuchMethodException me) { - // ok, so that didn't work - now try converting any primitive - // wrapper types to their primitive counterparts - try { - // if args is null the NullPointerException will get caught - // below and the right thing'll happen .. ugly but works - for (int i = 0; i < args.length; i++) { - if (args[i] instanceof Number) - argTypes[i] = byte.class; - else if (args[i] instanceof Boolean) - argTypes[i] = boolean.class; - else if (args[i] instanceof Character) - argTypes[i] = char.class; - } - obj = ReflectionUtils.createBean (null, className, - argTypes, args); - return obj.value; - } catch (Exception e) { - // throw the previous exception - throw me; - } - } - } catch (Exception e) { - throw new BSFException (BSFException.REASON_OTHER_ERROR, - e.getMessage (), e); - } - } - - /** - * Given a class return the type signature string fragment for it. - * That is, return "I" for int, "J" for long, ... etc.. - * - * @param cl class object for whom the signature fragment is needed. - * - * @return the string representing the type signature - */ - public static String getTypeSignatureString (Class cl) { - if (cl.isPrimitive ()) { - if (cl == boolean.class) - return "Z"; - else if (cl == byte.class) - return "B"; - else if (cl == char.class) - return "C"; - else if (cl == short.class) - return "S"; - else if (cl == int.class) - return "I"; - else if (cl == long.class) - return "J"; - else if (cl == float.class) - return "F"; - else if (cl == double.class) - return "D"; - else - return "V"; - } else { - StringBuffer sb = new StringBuffer ("L"); - sb.append (cl.getName ()); - sb.append (";"); - return sb.toString().replace ('.', '/'); - } - } - - /** - * Load a class using the class loader of given manager. If that fails - * try using a class loader that loads from the tempdir of the manager. - * - * @param mgr BSFManager who's classLoader and tempDir props are - * consulted - * @param name name of the class to load - * - * @return the loaded class - * - * @exception BSFException if something goes wrong. - */ - public static Class loadClass (BSFManager mgr, String name) - throws BSFException { - ClassLoader classLoader = mgr.getClassLoader (); - - try { - return (classLoader == null) ? - // Class.forName (name) - Thread.currentThread().getContextClassLoader().loadClass (name) - : classLoader.loadClass (name); - } catch (ClassNotFoundException e) { - // try to load it from the temp dir using my own class loader - try { - if (bsfCL == null) - bsfCL = new BSFClassLoader (); - bsfCL.setTempDir (mgr.getTempDir ()); - return bsfCL.loadClass (name); - } catch (ClassNotFoundException e2) { - throw new BSFException (BSFException.REASON_OTHER_ERROR, - "unable to load class '" + name + "':" + e, e); - } - } - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/IOUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/IOUtils.java deleted file mode 100644 index 45b5a0764..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/IOUtils.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Reader; -import java.io.StringWriter; - -/** - * This file is a collection of input/output utilities. - * - * @author Sanjiva Weerawarana - * @author Matthew J. Duftler - */ -public class IOUtils { - // debug flag - generates debug stuff if true - static boolean debug = false; - - ////////////////////////////////////////////////////////////////////////// - - public static String getStringFromReader (Reader reader) throws IOException { - BufferedReader bufIn = new BufferedReader(reader); - StringWriter swOut = new StringWriter(); - PrintWriter pwOut = new PrintWriter(swOut); - String tempLine; - - while ((tempLine = bufIn.readLine()) != null) { - pwOut.println(tempLine); - } - - pwOut.flush(); - - return swOut.toString(); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/IndentWriter.java b/src/main/java/com/volmit/iris/util/bsf/util/IndentWriter.java deleted file mode 100644 index 7141bc041..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/IndentWriter.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.Writer; - -/** - * An IndentWriter object behaves the same as a - * PrintWriter object, with the additional capability - * of being able to print strings that are prepended with a specified - * amount of spaces. - * - * @author Matthew J. Duftler - */ -public class IndentWriter extends PrintWriter -{ - /** - * Forwards its arguments to the PrintWriter constructor - * with the same signature. - */ - public IndentWriter(OutputStream out) - { - super(out); - } - /** - * Forwards its arguments to the PrintWriter constructor - * with the same signature. - */ - public IndentWriter(OutputStream out, boolean autoFlush) - { - super(out, autoFlush); - } - /** - * Forwards its arguments to the PrintWriter constructor - * with the same signature. - */ - public IndentWriter(Writer out) - { - super(out); - } - /** - * Forwards its arguments to the PrintWriter constructor - * with the same signature. - */ - public IndentWriter(Writer out, boolean autoFlush) - { - super(out, autoFlush); - } - /** - * Print the text (indented the specified amount) without inserting a linefeed. - * - * @param numberOfSpaces the number of spaces to indent the text. - * @param text the text to print. - */ - public void print(int numberOfSpaces, String text) - { - super.print(StringUtils.getChars(numberOfSpaces, ' ') + text); - } - /** - * Print the text (indented the specified amount) and insert a linefeed. - * - * @param numberOfSpaces the number of spaces to indent the text. - * @param text the text to print. - */ - public void println(int numberOfSpaces, String text) - { - super.println(StringUtils.getChars(numberOfSpaces, ' ') + text); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.c b/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.c deleted file mode 100644 index 0c18b0cdc..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2003,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include - -#include "JNIUtils.h" - -/***** - * - * NOTE: Whereever I think an exception may occur, I need to check - * whether it did and recover appropriately .. otherwise the behavior - * of JNI is undefined! - * - *****/ - -/* throw a BSFException with the given code and message. */ -void bsf_exception (JNIEnv *jenv, int code, char *msg) { - jclass bsfexceptclass = - (*jenv)->FindClass (jenv, "org/apache/bsf/BSFException"); - (*jenv)->ThrowNew (jenv, bsfexceptclass, msg); -} - -/* cvt a pointer to a Long object whose value is the pointer value */ -jobject bsf_pointer2longobj (JNIEnv *jenv, void *ptr) { - return bsf_makeLong (jenv, (long) ptr); -} - -/* cvt a Long object whose value is the pointer value to the pointer */ -void *bsf_longobj2pointer (JNIEnv *jenv, jobject lobj) { - jclass longclass = (*jenv)->FindClass (jenv, "java/lang/Long"); - jmethodID mi = (*jenv)->GetMethodID (jenv, longclass, "longValue", "()J"); - void *ptr = (void *) (*jenv)->CallLongMethod (jenv, lobj, mi); - return ptr; -} - -/* convert an object to a string obj */ -jstring bsf_obj2jstring (JNIEnv *jenv, jobject obj) { - jclass objclass = (*jenv)->GetObjectClass (jenv, obj); - jmethodID tostr = (*jenv)->GetMethodID (jenv, objclass, "toString", - "()Ljava/lang/String;"); - jstring strobj = (jstring) (*jenv)->CallObjectMethod (jenv, obj, tostr); - return strobj; -} - -/* cvt an object to a c-string .. wastes memory, but useful for debug */ -const char *bsf_obj2cstring (JNIEnv *jenv, jobject obj) { - return (*jenv)->GetStringUTFChars (jenv, - bsf_obj2jstring (jenv, obj), - 0); -} - -/* call the named method with the given args on the given bean */ -jobject bsf_createbean (JNIEnv *jenv, char *classname, jobjectArray args) { - jclass cl; - jmethodID mid; - jobject result; - - /* find the BSFUtils.createBean method ID if needed */ - cl = (*jenv)->FindClass (jenv, "org/apache/bsf/util/EngineUtils"); - mid = (*jenv)->GetStaticMethodID (jenv, cl, "createBean", - "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); - if ((*jenv)->ExceptionOccurred (jenv)) { - (*jenv)->ExceptionDescribe (jenv); - (*jenv)->ExceptionClear (jenv); - return 0; - } - - result = (*jenv)->CallStaticObjectMethod (jenv, cl, mid, - (*jenv)->NewStringUTF (jenv, - classname), - args); - if ((*jenv)->ExceptionOccurred (jenv)) { - (*jenv)->ExceptionDescribe (jenv); - (*jenv)->ExceptionClear (jenv); - /* I should really throw a BSF exception here and the caller should - check whether an exception was thrown and in that case return. - later. */ - return 0; - } else { - return result; - } -} - -/* call the named method with the given args on the given bean */ -jobject bsf_callmethod (JNIEnv *jenv, jobject target, - char *methodname, jobjectArray args) { - jclass cl; - jmethodID mid; - jobject result; - - /* find the BSFUtils.callBeanMethod method ID if needed */ - cl = (*jenv)->FindClass (jenv, "org/apache/bsf/util/EngineUtils"); - mid = (*jenv)->GetStaticMethodID (jenv, cl, "callBeanMethod", - "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); - if ((*jenv)->ExceptionOccurred (jenv)) { - (*jenv)->ExceptionDescribe (jenv); - (*jenv)->ExceptionClear (jenv); - return 0; - } - result = (*jenv)->CallStaticObjectMethod (jenv, cl, mid, target, - (*jenv)->NewStringUTF (jenv, - methodname), - args); - if ((*jenv)->ExceptionOccurred (jenv)) { - (*jenv)->ExceptionDescribe (jenv); - (*jenv)->ExceptionClear (jenv); - /* I should really throw a BSF exception here and the caller should - check whether an exception was thrown and in that case return. - later. */ - return 0; - } else { - return result; - } -} - -/* return the named bean from the given mgr's bean registry */ -jobject bsf_lookupbean (JNIEnv *jenv, jobject mgr, char *beanname) { - jmethodID lookupMethod; - jobject result; - - jclass bsfmgrclass = (*jenv)->GetObjectClass (jenv, mgr); - lookupMethod = - (*jenv)->GetMethodID (jenv, bsfmgrclass, "lookupBean", - "(Ljava/lang/String;)Ljava/lang/Object;"); - if ((*jenv)->ExceptionOccurred (jenv)) { - (*jenv)->ExceptionDescribe (jenv); - (*jenv)->ExceptionClear (jenv); - return 0; - } - - result = (*jenv)->CallObjectMethod (jenv, mgr, lookupMethod, - (*jenv)->NewStringUTF (jenv, beanname)); - if ((*jenv)->ExceptionOccurred (jenv)) { - (*jenv)->ExceptionDescribe (jenv); - (*jenv)->ExceptionClear (jenv); - /* I should really throw a BSF exception here and the caller should - check whether an exception was thrown and in that case return. - later. */ - return 0; - } else { - return result; - } -} - -/* return the type signature string component for the given type: - I for ints, J for long, ... */ -char *bsf_getTypeSignatureString (JNIEnv *jenv, jclass objclass) { - jclass cl = 0; - jmethodID mid = 0; - jstring str; - - cl = (*jenv)->FindClass (jenv, "org/apache/bsf/util/EngineUtils"); - mid = (*jenv)->GetStaticMethodID (jenv, cl, "getTypeSignatureString", - "(Ljava/lang/Class;)Ljava/lang/String;"); - if ((*jenv)->ExceptionOccurred (jenv)) { - (*jenv)->ExceptionDescribe (jenv); - (*jenv)->ExceptionClear (jenv); - return 0; - } - str = (jstring) (*jenv)->CallStaticObjectMethod (jenv, cl, mid, objclass); - return (char *) bsf_obj2cstring (jenv, str); -} - -/* make objects from primitives */ - -jobject bsf_makeBoolean (JNIEnv *jenv, int val) { - jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Boolean"); - jmethodID constructor = - (*jenv)->GetMethodID (jenv, classobj, "", "(Z)V"); - return (*jenv)->NewObject (jenv, classobj, constructor, (jboolean) val); -} - -jobject bsf_makeByte (JNIEnv *jenv, int val) { - jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Byte"); - jmethodID constructor = - (*jenv)->GetMethodID (jenv, classobj, "", "(B)V"); - return (*jenv)->NewObject (jenv, classobj, constructor, (jbyte) val); -} - -jobject bsf_makeShort (JNIEnv *jenv, int val) { - jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Short"); - jmethodID constructor = - (*jenv)->GetMethodID (jenv, classobj, "", "(S)V"); - return (*jenv)->NewObject (jenv, classobj, constructor, (jshort) val); -} - -jobject bsf_makeInteger (JNIEnv *jenv, int val) { - jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Integer"); - jmethodID constructor = - (*jenv)->GetMethodID (jenv, classobj, "", "(I)V"); - return (*jenv)->NewObject (jenv, classobj, constructor, (jint) val); -} - -jobject bsf_makeLong (JNIEnv *jenv, long val) { - jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Long"); - jmethodID constructor = - (*jenv)->GetMethodID (jenv, classobj, "", "(J)V"); - return (*jenv)->NewObject (jenv, classobj, constructor, (jlong) val); -} - -jobject bsf_makeFloat (JNIEnv *jenv, float val) { - jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Float"); - jmethodID constructor = - (*jenv)->GetMethodID (jenv, classobj, "", "(F)V"); - return (*jenv)->NewObject (jenv, classobj, constructor, (jfloat) val); -} - -jobject bsf_makeDouble (JNIEnv *jenv, double val) { - jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Double"); - jmethodID constructor = - (*jenv)->GetMethodID (jenv, classobj, "", "(D)V"); - return (*jenv)->NewObject (jenv, classobj, constructor, (jdouble) val); -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.h b/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.h deleted file mode 100644 index ffc83f65c..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/JNIUtils.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2003,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#if defined(__cplusplus) -extern "C" { -#endif - -/* throw a BSFException with the given message */ -extern void bsf_exception (JNIEnv *jenv, int code, char *msg); - -/* cvt a pointer to a Long object whose value is the pointer value */ -extern jobject bsf_pointer2longobj (JNIEnv *jenv, void *ptr); - -/* cvt a Long object whose value is the pointer value to the pointer */ -extern void *bsf_longobj2pointer (JNIEnv *jenv, jobject lobj); - -/* convert an object to a string obj */ -jstring bsf_obj2jstring (JNIEnv *jenv, jobject obj); - -/* cvt an object to a c-string .. wastes memory, but useful for debug */ -const char *bsf_obj2cstring (JNIEnv *jenv, jobject obj); - -/* create an instance of the named class with the given args */ -extern jobject bsf_createbean (JNIEnv *jenv, char *methodname, - jobjectArray args); - -/* call the named method with the given args on the given bean */ -extern jobject bsf_callmethod (JNIEnv *jenv, jobject target, - char *methodname, jobjectArray args); - -/* return the named bean from the given mgr's bean registry */ -extern jobject bsf_lookupbean (JNIEnv *jenv, jobject mgr, char *beanname); - -/* return the type signature string component for the given type: - I for ints, J for long, ... */ -extern char *bsf_getTypeSignatureString (JNIEnv *jenv, jclass objclass); - -/* make objects from primitives */ -extern jobject bsf_makeBoolean (JNIEnv *jenv, int val); -extern jobject bsf_makeByte (JNIEnv *jenv, int val); -extern jobject bsf_makeShort (JNIEnv *jenv, int val); -extern jobject bsf_makeInteger (JNIEnv *jenv, int val); -extern jobject bsf_makeLong (JNIEnv *jenv, long val); -extern jobject bsf_makeFloat (JNIEnv *jenv, float val); -extern jobject bsf_makeDouble (JNIEnv *jenv, double val); -#if defined(__cplusplus) -} -#endif diff --git a/src/main/java/com/volmit/iris/util/bsf/util/JavaUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/JavaUtils.java deleted file mode 100644 index f978a6548..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/JavaUtils.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.io.IOException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class JavaUtils { - // Temporarily copied from JavaEngine... - - private static Log logger; - - static { - logger = LogFactory.getLog((com.volmit.iris.util.bsf.util.JavaUtils.class) - .getName()); - } - - public static boolean JDKcompile(String fileName, String classPath) { - String option = (logger.isDebugEnabled()) ? "-g" : "-O"; - String args[] = { "javac", option, "-classpath", classPath, fileName }; - - logger.debug("JavaEngine: Compiling " + fileName); - logger.debug("JavaEngine: Classpath is " + classPath); - - try { - Process p = java.lang.Runtime.getRuntime().exec(args); - p.waitFor(); - return (p.exitValue() != 0); - } catch (IOException e) { - logger.error("ERROR: IO exception during exec(javac).", e); - } catch (SecurityException e) { - logger.error("ERROR: Unable to create subprocess to exec(javac).", - e); - } catch (InterruptedException e) { - logger.error("ERROR: Wait for exec(javac) was interrupted.", e); - } - return false; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/MethodUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/MethodUtils.java deleted file mode 100644 index b3161a897..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/MethodUtils.java +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Enumeration; -import java.util.Vector; - -/** - * This file is a collection of reflection utilities for dealing with - * methods and constructors. - * - * @author Sanjiva Weerawarana - * @author Joseph Kesselman - */ -public class MethodUtils { - - /** Internal Class for getEntryPoint(). Implements 15.11.2.2 MORE - SPECIFIC rules. - - Retains a list of methods (already known to match the - arguments). As each method is added, we check against past entries - to determine which if any is "more specific" -- defined as having - _all_ its arguments (not just a preponderance) be - method-convertable into those of another. If such a relationship - is found, the more-specific method is retained and the - less-specific method is discarded. At the end, if this has yielded - a single winner it is considered the Most Specific Method and - hence the one that should be invoked. Otherwise, a - NoSuchMethodException is thrown. - - PERFORMANCE VERSUS ARCHITECTURE: Arguably, this should "have-a" - Vector. But the code is 6% smaller, and possibly faster, if we - code it as "is-a" Vector. Since it's an inner class, nobody's - likely to abuse the privilage. - - Note: "Static" in the case of an inner class means "Does not - reference instance data in the outer class", and is required since - our caller is a static method. */ - private static class MoreSpecific - extends Vector - { - /** Submit an entry-point to the list. May be discarded if a past - entry is more specific, or may cause others to be discarded it - if is more specific. - - newEntry: Method or Constructor under consideration. - */ - void addItem (Object newEntry) - { - if(size()==0) - addElement(newEntry); - else - { - Class[] newargs=entryGetParameterTypes(newEntry); - boolean keep=true; - for (Enumeration e = elements(); - keep & e.hasMoreElements() ; - ) - { - Object oldEntry=e.nextElement(); - // CAVEAT: Implicit references to enclosing class! - Class[] oldargs=entryGetParameterTypes(oldEntry); - if(areMethodConvertable(oldargs,newargs)) - removeElement(oldEntry); // New more specific; discard old - else if(areMethodConvertable(newargs,oldargs)) - keep=false; // Old more specific; discard new - // Else they're tied. Keep both and hope someone beats both. - } - if(keep) - addElement(newEntry); - } - } - - /** Obtain the single Most Specific entry-point. If there is no clear - winner, or if the list is empty, throw NoSuchMethodException. - - Arguments describe the call we were hoping to resolve. They are - used to throw a nice verbose exception if something goes wrong. - */ - Object getMostSpecific(Class targetClass,String methodName, - Class[] argTypes,boolean isStaticReference) - throws NoSuchMethodException - { - if(size()==1) - return firstElement(); - if(size()>1) - { - StringBuffer buf=new StringBuffer(); - Enumeration e=elements(); - buf.append(e.nextElement()); - while(e.hasMoreElements()) - buf.append(" and ").append(e.nextElement()); - throw new NoSuchMethodException (callToString(targetClass, - methodName, - argTypes, - isStaticReference)+ - " is ambiguous. It matches "+ - buf.toString()); - } - return null; - } - } - - /** Convenience method: Test an entire parameter-list/argument-list pair - for isMethodConvertable(), qv. - */ - static private boolean areMethodConvertable(Class[] parms,Class[] args) - { - if(parms.length!=args.length) - return false; - - for(int i=0;i0) { - if(false) - { - // ????? Sanjiva has an ArrayToString method. Using it would - // save a few bytes, at cost of giving up some reusability. - } - else - { - buf.append(StringUtils.getClassName(argTypes[0])); - for (int i = 1; i < argTypes.length; i++) { - buf.append(",").append(StringUtils.getClassName(argTypes[i])); - } - } - } - else - buf.append("[none]"); - buf.append(")"); - return buf.toString(); - } - /** Utility function: obtain common data from either Method or - Constructor. (In lieu of an EntryPoint interface.) */ - static int entryGetModifiers(Object entry) - { - return (entry instanceof Method) - ? ((Method)entry).getModifiers() - : ((Constructor)entry).getModifiers(); - } - // The common lookup code would be much easier if Method and - // Constructor shared an "EntryPoint" Interface. Unfortunately, even - // though their APIs are almost identical, they don't. These calls - // are a workaround... at the cost of additional runtime overhead - // and some extra bytecodes. - // - // (A JDK bug report has been submitted requesting that they add the - // Interface; it would be easy, harmless, and useful.) - - /** Utility function: obtain common data from either Method or - Constructor. (In lieu of an EntryPoint interface.) */ - static String entryGetName(Object entry) - { - return (entry instanceof Method) - ? ((Method)entry).getName() - : ((Constructor)entry).getName(); - } - /** Utility function: obtain common data from either Method or - Constructor. (In lieu of an EntryPoint interface.) */ - static Class[] entryGetParameterTypes(Object entry) - { - return (entry instanceof Method) - ? ((Method)entry).getParameterTypes() - : ((Constructor)entry).getParameterTypes(); - } - /** Utility function: obtain common data from either Method or - Constructor. (In lieu of an EntryPoint interface.) */ - static String entryToString(Object entry) - { - return (entry instanceof Method) - ? ((Method)entry).toString() - : ((Constructor)entry).toString(); - } - ////////////////////////////////////////////////////////////////////////// - - /** Class.getConstructor() finds only the entry point (if any) - _exactly_ matching the specified argument types. Our implmentation - can decide between several imperfect matches, using the same - search algorithm as the Java compiler. - - Note that all constructors are static by definition, so - isStaticReference is true. - - @exception NoSuchMethodException if constructor not found. - */ - static public Constructor getConstructor(Class targetClass, Class[] argTypes) - throws SecurityException, NoSuchMethodException - { - return (Constructor) getEntryPoint(targetClass,null,argTypes,true); - } - ////////////////////////////////////////////////////////////////////////// - - /** - * Search for entry point, per Java Language Spec 1.0 - * as amended, verified by comparison against compiler behavior. - * - * @param targetClass Class object for the class to be queried. - * @param methodName Name of method to invoke, or null for constructor. - * Only Public methods will be accepted. - * @param argTypes Classes of intended arguments. Note that primitives - * must be specified via their TYPE equivalents, - * rather than as their wrapper classes -- Integer.TYPE - * rather than Integer. "null" may be passed in as an - * indication that you intend to invoke the method with - * a literal null argument and therefore can accept - * any object type in this position. - * @param isStaticReference If true, and if the target is a Class object, - * only static methods will be accepted as valid matches. - * - * @return a Method or Constructor of the appropriate signature - * - * @exception SecurityException if security violation - * @exception NoSuchMethodException if no such method - */ - static private Object getEntryPoint(Class targetClass, - String methodName, - Class[] argTypes, - boolean isStaticReference) - throws SecurityException, NoSuchMethodException - { - // 15.11.1: OBTAIN STARTING CLASS FOR SEARCH - Object m=null; - - // 15.11.2 DETERMINE ARGUMENT SIGNATURE - // (Passed in as argTypes array.) - - // Shortcut: If an exact match exists, return it. - try { - if(methodName!=null) - { - m=targetClass.getMethod (methodName, argTypes); - if(isStaticReference && - !Modifier.isStatic(entryGetModifiers(m)) ) - { - throw - new NoSuchMethodException (callToString (targetClass, - methodName, - argTypes, - isStaticReference)+ - " resolved to instance " + m); - } - return m; - } - else - return targetClass.getConstructor (argTypes); - - } catch (NoSuchMethodException e) { - // no-args has no alternatives! - if(argTypes==null || argTypes.length==0) - { - throw - new NoSuchMethodException (callToString (targetClass, - methodName, - argTypes, - isStaticReference)+ - " not found."); - } - // Else fall through. - } - - // Well, _that_ didn't work. Time to search for the Most Specific - // matching function. NOTE that conflicts are possible! - - // 15.11.2.1 ACCESSIBLE: We apparently need to gather from two - // sources to be sure we have both instance and static methods. - Object[] methods; - if(methodName!=null) - { - methods=targetClass.getMethods(); - } - else - { - methods=targetClass.getConstructors(); - } - if(0==methods.length) - { - throw new NoSuchMethodException("No methods!"); - } - - MoreSpecific best=new MoreSpecific(); - for(int i=0;i=primTypes.length) - return false; // Off the end - - for(argscore=0;argscore=primTypes.length) - return false; // Off the end - - // OK if ordered AND NOT char-to-smaller-than-int - return (argscore2) ); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/ObjInfo.java b/src/main/java/com/volmit/iris/util/bsf/util/ObjInfo.java deleted file mode 100644 index 2546f86e3..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/ObjInfo.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -/** - * An ObjInfo object is used by a compiler to track the name and - * type of a bean. - * - * @author Matthew J. Duftler - */ -public class ObjInfo -{ - static private String QUOTE_CHARS = "\'\"", - EXEC_CHARS = "(="; - public String objName; - public Class objClass; - - public ObjInfo(Class objClass, String objName) - { - this.objClass = objClass; - this.objName = objName; - } - public boolean isExecutable() - { - char[] chars = objName.toCharArray(); - char openingChar = ' '; - boolean inString = false, - inEscapeSequence = false; - - for (int i = 0; i < chars.length; i++) - { - if (inEscapeSequence) - { - inEscapeSequence = false; - } - else if (QUOTE_CHARS.indexOf(chars[i]) != -1) - { - if (!inString) - { - openingChar = chars[i]; - inString = true; - } - else - { - if (chars[i] == openingChar) - { - inString = false; - } - } - } - else if (EXEC_CHARS.indexOf(chars[i]) != -1) - { - if (!inString) - { - return true; - } - } - else if (inString && chars[i] == '\\') - { - inEscapeSequence = true; - } - } - - return false; - } - public boolean isValueReturning() - { - return (objClass != void.class && objClass != Void.class); - } - public String toString() - { - return StringUtils.getClassName(objClass) + " " + objName; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/ObjectRegistry.java b/src/main/java/com/volmit/iris/util/bsf/util/ObjectRegistry.java deleted file mode 100644 index af6b72267..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/ObjectRegistry.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.util.Hashtable; - -/** - * The ObjectRegistry is used to do name-to-object reference lookups. - * If an ObjectRegistry is passed as a constructor argument, then this - * ObjectRegistry will be a cascading registry: when a lookup is - * invoked, it will first look in its own table for a name, and if it's not - * there, it will cascade to the parent ObjectRegistry. - * All registration is always local. [??] - * - * @author Sanjiva Weerawarana - * @author Matthew J. Duftler - */ -public class ObjectRegistry { - Hashtable reg = new Hashtable (); - ObjectRegistry parent = null; - - public ObjectRegistry () { - } - public ObjectRegistry (ObjectRegistry parent) { - this.parent = parent; - } - // lookup an object: cascade up if needed - public Object lookup (String name) throws IllegalArgumentException { - Object obj = reg.get (name); - - if (obj == null && parent != null) { - obj = parent.lookup (name); - } - - if (obj == null) { - throw new IllegalArgumentException ("object '" + name + "' not in registry"); - } - - return obj; - } - // register an object - public void register (String name, Object obj) { - reg.put (name, obj); - } - // unregister an object (silent if unknown name) - public void unregister (String name) { - reg.remove (name); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/ReflectionUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/ReflectionUtils.java deleted file mode 100644 index ae9e0c36a..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/ReflectionUtils.java +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.beans.BeanInfo; -import java.beans.Beans; -import java.beans.EventSetDescriptor; -import java.beans.FeatureDescriptor; -import java.beans.IndexedPropertyDescriptor; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import com.volmit.iris.util.bsf.util.event.EventAdapter; -import com.volmit.iris.util.bsf.util.event.EventAdapterRegistry; -import com.volmit.iris.util.bsf.util.event.EventProcessor; -import com.volmit.iris.util.bsf.util.type.TypeConvertor; -import com.volmit.iris.util.bsf.util.type.TypeConvertorRegistry; - -/** - * This file is a collection of reflection utilities. There are utilities - * for creating beans, getting bean infos, setting/getting properties, - * and binding events. - * - * @author Sanjiva Weerawarana - * @author Joseph Kesselman - */ -public class ReflectionUtils { - - ////////////////////////////////////////////////////////////////////////// - - /** - * Add an event processor as a listener to some event coming out of an - * object. - * - * @param source event source - * @param eventSetName name of event set from event src to bind to - * @param processor event processor the event should be delegated to - * when it occurs; either via processEvent or - * processExceptionableEvent. - * - * @exception IntrospectionException if unable to introspect - * @exception IllegalArgumentException if event set is unknown - * @exception IllegalAccessException if the event adapter class or - * initializer is not accessible. - * @exception InstantiationException if event adapter instantiation fails - * @exception InvocationTargetException if something goes wrong while - * running add event listener method - */ - public static void addEventListener (Object source, String eventSetName, - EventProcessor processor) - throws IntrospectionException, IllegalArgumentException, - IllegalAccessException, InstantiationException, - InvocationTargetException { - // find the event set descriptor for this event - BeanInfo bi = Introspector.getBeanInfo (source.getClass ()); - EventSetDescriptor esd = (EventSetDescriptor) - findFeatureByName ("event", eventSetName, bi.getEventSetDescriptors ()); - - if (esd == null) // no events found, maybe a proxy from OpenOffice.org? - { - throw new IllegalArgumentException ("event set '" + eventSetName + - "' unknown for source type '" + source.getClass () + "'"); - } - - // get the class object for the event - Class listenerType=esd.getListenerType(); // get ListenerType class object from EventSetDescriptor - - // find an event adapter class of the right type - Class adapterClass = EventAdapterRegistry.lookup (listenerType); - if (adapterClass == null) { - throw new IllegalArgumentException ("event adapter for listener type " + - "'" + listenerType + "' (eventset " + - "'" + eventSetName + "') unknown"); - } - - // create the event adapter and give it the event processor - EventAdapter adapter = (EventAdapter) adapterClass.newInstance (); - adapter.setEventProcessor (processor); - - // bind the adapter to the source bean - Method addListenerMethod; - Object[] args; - if (eventSetName.equals ("propertyChange") || - eventSetName.equals ("vetoableChange")) { - // In Java 1.2, beans may have direct listener adding methods - // for property and vetoable change events which take the - // property name as a filter to be applied at the event source. - // The filter property of the event processor should be used - // in this case to support the source-side filtering. - // - // ** TBD **: the following two lines need to change appropriately - addListenerMethod = esd.getAddListenerMethod (); - args = new Object[] {adapter}; - } - else - { - addListenerMethod = esd.getAddListenerMethod (); - args = new Object[] {adapter}; - } - addListenerMethod.invoke (source, args); - } - ////////////////////////////////////////////////////////////////////////// - - - /** - * Create a bean using given class loader and using the appropriate - * constructor for the given args of the given arg types. - - * @param cld the class loader to use. If null, Class.forName is used. - * @param className name of class to instantiate - * @param argTypes array of argument types - * @param args array of arguments - * - * @return the newly created bean - * - * @exception ClassNotFoundException if class is not loaded - * @exception NoSuchMethodException if constructor can't be found - * @exception InstantiationException if class can't be instantiated - * @exception IllegalAccessException if class is not accessible - * @exception IllegalArgumentException if argument problem - * @exception InvocationTargetException if constructor excepted - * @exception IOException if I/O error in beans.instantiate - */ - public static Bean createBean (ClassLoader cld, String className, - Class[] argTypes, Object[] args) - throws ClassNotFoundException, NoSuchMethodException, - InstantiationException, IllegalAccessException, - IllegalArgumentException, InvocationTargetException, - IOException { - if (argTypes != null) { - // find the right constructor and use that to create bean - Class cl = (cld != null) ? cld.loadClass (className) - : Thread.currentThread().getContextClassLoader().loadClass (className); // rgf, 2006-01-05 - // : Class.forName (className); - - Constructor c = MethodUtils.getConstructor (cl, argTypes); - return new Bean (cl, c.newInstance (args)); - } else { - // create the bean with no args constructor - Object obj = Beans.instantiate (cld, className); - return new Bean (obj.getClass (), obj); - } - } - ////////////////////////////////////////////////////////////////////////// - - /** - * Create a bean using given class loader and using the appropriate - * constructor for the given args. Figures out the arg types and - * calls above. - - * @param cld the class loader to use. If null, Class.forName is used. - * @param className name of class to instantiate - * @param args array of arguments - * - * @return the newly created bean - * - * @exception ClassNotFoundException if class is not loaded - * @exception NoSuchMethodException if constructor can't be found - * @exception InstantiationException if class can't be instantiated - * @exception IllegalAccessException if class is not accessible - * @exception IllegalArgumentException if argument problem - * @exception InvocationTargetException if constructor excepted - * @exception IOException if I/O error in beans.instantiate - */ - public static Bean createBean (ClassLoader cld, String className, - Object[] args) - throws ClassNotFoundException, NoSuchMethodException, - InstantiationException, IllegalAccessException, - IllegalArgumentException, InvocationTargetException, - IOException { - Class[] argTypes = null; - if (args != null) { - argTypes = new Class[args.length]; - for (int i = 0; i < args.length; i++) { - argTypes[i] = (args[i] != null) ? args[i].getClass () : null; - } - } - return createBean (cld, className, argTypes, args); - } - ////////////////////////////////////////////////////////////////////////// - - /** - * locate the item in the fds array whose name is as given. returns - * null if not found. - */ - private static - FeatureDescriptor findFeatureByName (String featureType, String name, - FeatureDescriptor[] fds) { - for (int i = 0; i < fds.length; i++) { - if (name.equals (fds[i].getName())) { - return fds[i]; - } - } - return null; - } - public static Bean getField (Object target, String fieldName) - throws IllegalArgumentException, IllegalAccessException { - // This is to handle how we do static fields. - Class targetClass = (target instanceof Class) - ? (Class) target - : target.getClass (); - - try { - Field f = targetClass.getField (fieldName); - Class fieldType = f.getType (); - - // Get the value and return it. - Object value = f.get (target); - return new Bean (fieldType, value); - } catch (NoSuchFieldException e) { - throw new IllegalArgumentException ("field '" + fieldName + "' is " + - "unknown for '" + target + "'"); - } - } - ////////////////////////////////////////////////////////////////////////// - - /** - * Get a property of a bean. - * - * @param target the object whose prop is to be gotten - * @param propName name of the property to set - * @param index index to get (if property is indexed) - * - * @exception IntrospectionException if unable to introspect - * @exception IllegalArgumentException if problems with args: if the - * property is unknown, or if the property is given an index - * when its not, or if the property is not writeable, or if - * the given value cannot be assigned to the it (type mismatch). - * @exception IllegalAccessException if read method is not accessible - * @exception InvocationTargetException if read method excepts - */ - public static Bean getProperty (Object target, String propName, - Integer index) - throws IntrospectionException, IllegalArgumentException, - IllegalAccessException, InvocationTargetException { - // find the property descriptor - BeanInfo bi = Introspector.getBeanInfo (target.getClass ()); - PropertyDescriptor pd = (PropertyDescriptor) - findFeatureByName ("property", propName, bi.getPropertyDescriptors ()); - if (pd == null) { - throw new IllegalArgumentException ("property '" + propName + "' is " + - "unknown for '" + target + "'"); - } - - // get read method and type of property - Method rm; - Class propType; - if (index != null) { - // if index != null, then property is indexed - pd better be so too - if (!(pd instanceof IndexedPropertyDescriptor)) { - throw new IllegalArgumentException ("attempt to get non-indexed " + - "property '" + propName + - "' as being indexed"); - } - IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd; - rm = ipd.getIndexedReadMethod (); - propType = ipd.getIndexedPropertyType (); - } else { - rm = pd.getReadMethod (); - propType = pd.getPropertyType (); - } - - if (rm == null) { - throw new IllegalArgumentException ("property '" + propName + - "' is not readable"); - } - - // now get the value - Object propVal = null; - if (index != null) { - propVal = rm.invoke (target, new Object[] {index}); - } else { - propVal = rm.invoke (target, null); - } - return new Bean (propType, propVal); - } - public static void setField (Object target, String fieldName, Bean value, - TypeConvertorRegistry tcr) - throws IllegalArgumentException, IllegalAccessException { - // This is to handle how we do static fields. - Class targetClass = (target instanceof Class) - ? (Class) target - : target.getClass (); - - try { - Field f = targetClass.getField (fieldName); - Class fieldType = f.getType (); - - // type convert the value if necessary - Object fieldVal = null; - boolean okeydokey = true; - if (fieldType.isAssignableFrom (value.type)) { - fieldVal = value.value; - } else if (tcr != null) { - TypeConvertor cvtor = tcr.lookup (value.type, fieldType); - if (cvtor != null) { - fieldVal = cvtor.convert (value.type, fieldType, value.value); - } else { - okeydokey = false; - } - } else { - okeydokey = false; - } - if (!okeydokey) { - throw new IllegalArgumentException ("unable to assign '" + value.value + - "' to field '" + fieldName + "'"); - } - - // now set the value - f.set (target, fieldVal); - } catch (NoSuchFieldException e) { - throw new IllegalArgumentException ("field '" + fieldName + "' is " + - "unknown for '" + target + "'"); - } - } - ////////////////////////////////////////////////////////////////////////// - - /** - * Set a property of a bean to a given value. - * - * @param target the object whose prop is to be set - * @param propName name of the property to set - * @param index index to set (if property is indexed) - * @param value the property value - * @param valueType the type of the above (needed when its null) - * @param tcr type convertor registry to use to convert value type to - * property type if necessary - * - * @exception IntrospectionException if unable to introspect - * @exception IllegalArgumentException if problems with args: if the - * property is unknown, or if the property is given an index - * when its not, or if the property is not writeable, or if - * the given value cannot be assigned to the it (type mismatch). - * @exception IllegalAccessException if write method is not accessible - * @exception InvocationTargetException if write method excepts - */ - public static void setProperty (Object target, String propName, - Integer index, Object value, - Class valueType, TypeConvertorRegistry tcr) - throws IntrospectionException, IllegalArgumentException, - IllegalAccessException, InvocationTargetException { - // find the property descriptor - BeanInfo bi = Introspector.getBeanInfo (target.getClass ()); - PropertyDescriptor pd = (PropertyDescriptor) - findFeatureByName ("property", propName, bi.getPropertyDescriptors ()); - if (pd == null) { - throw new IllegalArgumentException ("property '" + propName + "' is " + - "unknown for '" + target + "'"); - } - - // get write method and type of property - Method wm; - Class propType; - if (index != null) { - // if index != null, then property is indexed - pd better be so too - if (!(pd instanceof IndexedPropertyDescriptor)) { - throw new IllegalArgumentException ("attempt to set non-indexed " + - "property '" + propName + - "' as being indexed"); - } - IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd; - wm = ipd.getIndexedWriteMethod (); - propType = ipd.getIndexedPropertyType (); - } else { - wm = pd.getWriteMethod (); - propType = pd.getPropertyType (); - } - - if (wm == null) { - throw new IllegalArgumentException ("property '" + propName + - "' is not writeable"); - } - - // type convert the value if necessary - Object propVal = null; - boolean okeydokey = true; - if (propType.isAssignableFrom (valueType)) { - propVal = value; - } else if (tcr != null) { - TypeConvertor cvtor = tcr.lookup (valueType, propType); - if (cvtor != null) { - propVal = cvtor.convert (valueType, propType, value); - } else { - okeydokey = false; - } - } else { - okeydokey = false; - } - if (!okeydokey) { - throw new IllegalArgumentException ("unable to assign '" + value + - "' to property '" + propName + "'"); - } - - // now set the value - if (index != null) { - wm.invoke (target, new Object[] {index, propVal}); - } else { - wm.invoke (target, new Object[] {propVal}); - } - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/ScriptSymbolTable.java b/src/main/java/com/volmit/iris/util/bsf/util/ScriptSymbolTable.java deleted file mode 100644 index 358e365eb..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/ScriptSymbolTable.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.util.Hashtable; - -/** - * An ScriptSymbolTable object is used by a CodeBuffer - * object to implement nested scopes. - * - * @author Matthew J. Duftler - */ -class ScriptSymbolTable extends Hashtable -{ - private Hashtable parentTable; - - ScriptSymbolTable(Hashtable parentTable) - { - this.parentTable = parentTable; - } - public synchronized Object get(Object key) - { - Object ret = super.get(key); - - if (ret == null && parentTable != null) - ret = parentTable.get(key); - - return ret; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/StringUtils.java b/src/main/java/com/volmit/iris/util/bsf/util/StringUtils.java deleted file mode 100644 index b512ffc76..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/StringUtils.java +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util; - -import java.beans.Introspector; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.StringTokenizer; -import java.util.Vector; - -/** - * Deals with strings (probably need to elaborate some more). - * - * @author Matthew J. Duftler - */ -public class StringUtils -{ - public static final String lineSeparator = - System.getProperty("line.separator", "\n"); - public static final String lineSeparatorStr = cleanString(lineSeparator); - - public static String classNameToVarName(String className) - { - // Might represent an array. - int arrayDim = 0; - - while (className.endsWith("[]")) - { - className = className.substring(0, className.length() - 2); - arrayDim++; - } - - int iLastPeriod = className.lastIndexOf('.'); - String varName = Introspector.decapitalize( - iLastPeriod != -1 - ? className.substring(iLastPeriod + 1) - : className); - - if (arrayDim > 0) - { - varName += "_" + arrayDim + "D"; - } - - return getValidIdentifierName(varName); - } - // Ensure that escape sequences are passed through properly. - public static String cleanString(String str) - { - if (str == null) - return null; - else - { - char[] charArray = str.toCharArray(); - StringBuffer sBuf = new StringBuffer(); - - for (int i = 0; i < charArray.length; i++) - switch (charArray[i]) - { - case '\"' : sBuf.append("\\\""); - break; - case '\\' : sBuf.append("\\\\"); - break; - case '\n' : sBuf.append("\\n"); - break; - case '\r' : sBuf.append("\\r"); - break; - default : sBuf.append(charArray[i]); - break; - } - - return sBuf.toString(); - } - } - /** - * Get a string consisting of numberOfChars theChars. - * - * @return a string consisting of numberOfChars theChars. - */ - public static String getChars(int numberOfChars, char theChar) - { - if (numberOfChars <= 0) - return ""; - - StringBuffer sRet = new StringBuffer(numberOfChars); - - for (int i = 0; i < numberOfChars; i++) - sRet.append(theChar); - - return sRet.toString(); - } - /* - This method will return the correct name for a class object representing - a primitive, a single instance of a class, as well as n-dimensional arrays - of primitives or instances. This logic is needed to handle the string returned - from Class.getName(). If the class object represents a single instance (or - a primitive), Class.getName() returns the fully-qualified name of the class - and no further work is needed. However, if the class object represents an - array (of n dimensions), Class.getName() returns a Descriptor (the Descriptor - grammar is defined in section 4.3 of the Java VM Spec). This method will - parse the Descriptor if necessary. - */ - public static String getClassName(Class targetClass) - { - String className = targetClass.getName(); - - return targetClass.isArray() ? parseDescriptor(className) : className; - } - public static String getCommaListFromVector(Vector sourceVector) - { - StringBuffer strBuf = new StringBuffer(); - - for (int i = 0; i < sourceVector.size(); i++) - { - strBuf.append((i > 0 ? ", " : "") + - sourceVector.elementAt(i)); - } - - return strBuf.toString(); - } - /* - Returns a Reader for reading from the specified resource, if the resource - points to a stream. - */ - public static Reader getContentAsReader(URL url) throws SecurityException, - IllegalArgumentException, - IOException - { - if (url == null) - { - throw new IllegalArgumentException("URL cannot be null."); - } - - try - { - Object content = url.getContent(); - - if (content == null) - { - throw new IllegalArgumentException("No content."); - } - - if (content instanceof InputStream) - { - Reader in = new InputStreamReader((InputStream)content); - - if (in.ready()) - { - return in; - } - else - { - throw new FileNotFoundException(); - } - } - else - { - throw new IllegalArgumentException((content instanceof String) - ? (String)content - : "This URL points to a: " + - StringUtils.getClassName(content.getClass())); - } - } - catch (SecurityException e) - { - throw new SecurityException("Your JVM's SecurityManager has disallowed this."); - } - catch (FileNotFoundException e) - { - throw new FileNotFoundException("This file was not found: " + url); - } - } - /* - Shorthand for: IOUtils.getStringFromReader(getContentAsReader(url)). - */ - public static String getContentAsString(URL url) throws SecurityException, - IllegalArgumentException, - IOException - { - return IOUtils.getStringFromReader(getContentAsReader(url)); - } - // Handles multi-line strings. - public static String getSafeString(String scriptStr) - { - BufferedReader in = new BufferedReader(new StringReader(scriptStr)); - StringBuffer strBuf = new StringBuffer(); - String tempLine, - previousLine = null; - - try - { - while ((tempLine = in.readLine()) != null) - { - if (previousLine != null) - { - strBuf.append("\"" + previousLine + lineSeparatorStr + "\" +" + - lineSeparator); - } - - previousLine = cleanString(tempLine); - } - } - catch (IOException e) - { - } - - strBuf.append("\"" + (previousLine != null ? previousLine : "") + "\"" + - lineSeparator); - - return strBuf.toString(); - } - /* - */ - public static URL getURL(URL contextURL, String spec) throws MalformedURLException - { - return getURL(contextURL, spec, 1); - } - /* - The recursiveDepth argument is used to insure that the algorithm gives up - after hunting 2 levels up in the contextURL's path. - */ - private static URL getURL(URL contextURL, String spec, int recursiveDepth) - throws MalformedURLException - { - URL url = null; - - try - { - url = new URL(contextURL, spec); - - try - { - url.openStream(); - } - catch (IOException ioe1) - { - throw new MalformedURLException("This file was not found: " + url); - } - } - catch (MalformedURLException e1) - { - url = new URL("file", "", spec); - - try - { - url.openStream(); - } - catch (IOException ioe2) - { - if (contextURL != null) - { - String contextFileName = contextURL.getFile(); - String parentName = new File(contextFileName).getParent(); - - if (parentName != null && recursiveDepth < 3) - { - return getURL(new URL("file", "", parentName + '/'), - spec, - recursiveDepth + 1); - } - } - - throw new MalformedURLException("This file was not found: " + url); - } - } - - return url; - } - public static String getValidIdentifierName(String identifierName) - { - if (identifierName == null || identifierName.length() == 0) - return null; - - StringBuffer strBuf = new StringBuffer(); - - char[] chars = identifierName.toCharArray(); - - strBuf.append(Character.isJavaIdentifierStart(chars[0]) - ? chars[0] - : '_' - ); - - for (int i = 1; i < chars.length; i++) - { - strBuf.append(Character.isJavaIdentifierPart(chars[i]) - ? chars[i] - : '_' - ); - } - - return strBuf.toString(); - } - public static boolean isValidIdentifierName(String identifierName) - { - if (identifierName == null || identifierName.length() == 0) - return false; - - char[] chars = identifierName.toCharArray(); - - if (!Character.isJavaIdentifierStart(chars[0])) - return false; - - for (int i = 1; i < chars.length; i++) - if (!Character.isJavaIdentifierPart(chars[i])) - return false; - - return true; - } - public static boolean isValidPackageName(String packageName) - { - if (packageName == null) - return false; - else if (packageName.length() == 0) - // Empty is ok. - return true; - - StringTokenizer strTok = new StringTokenizer(packageName, ".", true); - - // Should have an odd number of tokens (including '.' delimiters). - if (strTok.countTokens() % 2 != 1) - return false; - - // Must start with a valid identifier name. - if (!isValidIdentifierName(strTok.nextToken())) - return false; - - // ... followed by 0 or more of ".ValidIdentifier". - while (strTok.hasMoreTokens()) - { - // Must be a '.'. - if (!strTok.nextToken().equals(".")) - return false; - - // Must be a valid identifier name. - if (strTok.hasMoreTokens()) - { - if (!isValidIdentifierName(strTok.nextToken())) - return false; - } - else - return false; - } - - return true; - } - /* - See the comment above for getClassName(targetClass)... - */ - private static String parseDescriptor(String className) - { - char[] classNameChars = className.toCharArray(); - int arrayDim = 0; - int i = 0; - - while (classNameChars[i] == '[') - { - arrayDim++; - i++; - } - - StringBuffer classNameBuf = new StringBuffer(); - - switch (classNameChars[i++]) - { - case 'B' : classNameBuf.append("byte"); - break; - case 'C' : classNameBuf.append("char"); - break; - case 'D' : classNameBuf.append("double"); - break; - case 'F' : classNameBuf.append("float"); - break; - case 'I' : classNameBuf.append("int"); - break; - case 'J' : classNameBuf.append("long"); - break; - case 'S' : classNameBuf.append("short"); - break; - case 'Z' : classNameBuf.append("boolean"); - break; - case 'L' : classNameBuf.append(classNameChars, - i, classNameChars.length - i - 1); - break; - } - - for (i = 0; i < arrayDim; i++) - classNameBuf.append("[]"); - - return classNameBuf.toString(); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/cf/CFDriver.java b/src/main/java/com/volmit/iris/util/bsf/util/cf/CFDriver.java deleted file mode 100644 index 90352395b..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/cf/CFDriver.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.cf; - -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.Writer; - -/** - * This is an example of how a CodeFormatter bean can be used. - *

- * The CFDriver is a stand-alone tool that will instantiate a - * CodeFormatter bean, configure it according to your - * command-line arguments, and invoke the formatting. Since the - * default source of input is stdin, and the default - * target for output is stdout, a CFDriver - * can also be used as a filter. - * - * @see CodeFormatter - * - * @version 1.0 - * @author Matthew J. Duftler - */ -public class CFDriver -{ - /** - * Not used. - */ - public CFDriver() - { - } - /** - * A driver for CodeFormatter. - *

- * Usage: - *

-	*  java org.apache.cf.CFDriver [args]
-	*

- * args: - *

- * [-in fileName] default: <STDIN> - * [-out fileName] default: <STDOUT> - * [-maxLine length] default: 74 - * [-step size] default: 2 - * [-delim group] default: (+ - * [-sdelim group] default: , - *

- */ - public static void main(String[] argv) - { - if (argv.length % 2 == 0) - { - String inFile = null, - outFile = null, - maxLine = null, - indStep = null, - delim = null, - sDelim = null; - Reader in = null; - Writer out = null; - CodeFormatter cf = new CodeFormatter(); - - for (int i = 0; i < argv.length; i += 2) - { - if (argv[i].startsWith("-i")) - inFile = argv[i + 1]; - else if (argv[i].startsWith("-o")) - outFile = argv[i + 1]; - else if (argv[i].startsWith("-m")) - maxLine = argv[i + 1]; - else if (argv[i].startsWith("-st")) - indStep = argv[i + 1]; - else if (argv[i].startsWith("-d")) - delim = argv[i + 1]; - else if (argv[i].startsWith("-sd")) - sDelim = argv[i + 1]; - } - - if (inFile != null) - { - try - { - in = new FileReader(inFile); - } - catch (FileNotFoundException e) - { - printError("Cannot open input file: " + inFile); - - return; - } - } - else - { - in = new InputStreamReader(System.in); - } - - if (outFile != null) - { - try - { - out = new FileWriter(outFile); - } - catch (IOException e) - { - printError("Cannot open output file: " + outFile); - - return; - } - } - else - { - out = new OutputStreamWriter(System.out); - } - - if (maxLine != null) - { - try - { - cf.setMaxLineLength(Integer.parseInt(maxLine)); - } - catch (NumberFormatException nfe) - { - printError("Not a valid integer: " + maxLine); - - return; - } - } - - if (indStep != null) - { - try - { - cf.setIndentationStep(Integer.parseInt(indStep)); - } - catch (NumberFormatException nfe) - { - printError("Not a valid integer: " + indStep); - - return; - } - } - - if (delim != null) - cf.setDelimiters(delim); - - if (sDelim != null) - cf.setStickyDelimiters(sDelim); - - cf.formatCode(in, out); - } - else - printHelp(); - } - private static void printError(String errMsg) - { - System.err.println("ERROR: " + errMsg); - } - private static void printHelp() - { - System.out.println("Usage:"); - System.out.println(); - System.out.println(" java " + CFDriver.class.getName() + " [args]"); - System.out.println(); - System.out.println(" args:"); - System.out.println(); - System.out.println(" [-in fileName] default: "); - System.out.println(" [-out fileName] default: "); - System.out.println(" [-maxLine length] default: " + - CodeFormatter.DEFAULT_MAX); - System.out.println(" [-step size] default: " + - CodeFormatter.DEFAULT_STEP); - System.out.println(" [-delim group] default: " + - CodeFormatter.DEFAULT_DELIM); - System.out.println(" [-sdelim group] default: " + - CodeFormatter.DEFAULT_S_DELIM); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/cf/CodeFormatter.java b/src/main/java/com/volmit/iris/util/bsf/util/cf/CodeFormatter.java deleted file mode 100644 index de3e17d2a..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/cf/CodeFormatter.java +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.cf; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; - -import com.volmit.iris.util.bsf.util.IndentWriter; -import com.volmit.iris.util.bsf.util.StringUtils; - -/** - * A CodeFormatter bean is used to format raw Java code. It - * indents, word-wraps, and replaces tab characters with an amount of space - * characters equal to the size of the indentationStep property. - * To create and use a CodeFormatter, you simply instantiate a - * new CodeFormatter bean, and invoke - * formatCode(Reader source, Writer target) with appropriate - * arguments. - * - * @version 1.0 - * @author Matthew J. Duftler - */ -public class CodeFormatter -{ - /** - * The default maximum line length. - */ - public static final int DEFAULT_MAX = 74; - /** - * The default size of the indentation step. - */ - public static final int DEFAULT_STEP = 2; - /** - * The default set of delimiters. - */ - public static final String DEFAULT_DELIM = "(+"; - /** - * The default set of sticky delimiters. - */ - public static final String DEFAULT_S_DELIM = ","; - - // Configurable Parameters - private int maxLineLength = DEFAULT_MAX; - private int indentationStep = DEFAULT_STEP; - private String delimiters = DEFAULT_DELIM; - private String stickyDelimiters = DEFAULT_S_DELIM; - - // Global Variables - private int indent; - private int hangingIndent; - private int origIndent; - private boolean inCPP_Comment; - - private void addTok(StringBuffer targetBuf, StringBuffer tokBuf, - IndentWriter out) - { - int tokLength = tokBuf.length(), - targetLength = targetBuf.length(); - - if (indent + targetLength + tokLength > maxLineLength) - { - if (targetLength == 0) - { - out.println(indent, tokBuf.toString()); - indent = hangingIndent; - targetBuf.setLength(0); - - return; - } - else - { - out.println(indent, targetBuf.toString().trim()); - indent = hangingIndent; - targetBuf.setLength(0); - } - } - - targetBuf.append(tokBuf.toString()); - - return; - } - /** - * Formats the code read from source, and writes the formatted - * code to target. - * - * @param source where to read the unformatted code from. - * @param target where to write the formatted code to. - */ - public void formatCode(Reader source, Writer target) - { - String line; - BufferedReader in = new BufferedReader(source); - IndentWriter out = new IndentWriter(new BufferedWriter(target), true); - - try - { - origIndent = 0; - inCPP_Comment = false; - - while ((line = in.readLine()) != null) - { - line = line.trim(); - - if (line.length() > 0) - { - indent = origIndent; - hangingIndent = indent + indentationStep; - printLine(line, out); - } - else - out.println(); - } - } - catch (IOException e) - { - e.printStackTrace(); - } - } - /** - * Gets the set of delimiters. - * - * @return the set of delimiters. - * @see #setDelimiters - */ - public String getDelimiters() - { - return delimiters; - } - /** - * Gets the size of the indentation step. - * - * @return the size of the indentation step. - * @see #setIndentationStep - */ - public int getIndentationStep() - { - return indentationStep; - } - /** - * Gets the maximum line length. - * - * @return the maximum line length. - * @see #setMaxLineLength - */ - public int getMaxLineLength() - { - return maxLineLength; - } - /** - * Gets the set of sticky delimiters. - * - * @return the set of sticky delimiters. - * @see #setStickyDelimiters - */ - public String getStickyDelimiters() - { - return stickyDelimiters; - } - private void printLine(String line, IndentWriter out) - { - char[] source = line.toCharArray(); - char ch; - char quoteChar = ' '; - boolean inEscapeSequence = false; - boolean inString = false; - StringBuffer tokBuf = new StringBuffer(), - targetBuf = new StringBuffer(hangingIndent + line.length()); - - for (int i = 0; i < source.length; i++) - { - ch = source[i]; - - if (inEscapeSequence) - { - tokBuf.append(ch); - inEscapeSequence = false; - } - else - { - if (inString) - { - switch (ch) - { - case '\\' : - tokBuf.append('\\'); - inEscapeSequence = true; - break; - case '\'' : - case '\"' : - tokBuf.append(ch); - - if (ch == quoteChar) - { - addTok(targetBuf, tokBuf, out); - tokBuf.setLength(0); - inString = false; - } - break; - case 9 : // pass thru tab characters... - tokBuf.append(ch); - break; - default : - if (ch > 31) - tokBuf.append(ch); - break; - } - } - else // !inString - { - if (inCPP_Comment) - { - tokBuf.append(ch); - - if (ch == '/' && i > 0 && source[i - 1] == '*') - inCPP_Comment = false; - } - else - { - switch (ch) - { - case '/' : - tokBuf.append(ch); - - if (i > 0 && source[i - 1] == '/') - { - String tokStr = tokBuf.append(source, - i + 1, - source.length - (i + 1)).toString(); - - out.println(indent, targetBuf.append(tokStr).toString()); - - return; - } - break; - case '*' : - tokBuf.append(ch); - - if (i > 0 && source[i - 1] == '/') - inCPP_Comment = true; - break; - case '\'' : - case '\"' : - addTok(targetBuf, tokBuf, out); - tokBuf.setLength(0); - tokBuf.append(ch); - quoteChar = ch; - inString = true; - break; - case 9 : // replace tab characters... - tokBuf.append(StringUtils.getChars(indentationStep, ' ')); - break; - case '{' : - tokBuf.append(ch); - origIndent += indentationStep; - break; - case '}' : - tokBuf.append(ch); - origIndent -= indentationStep; - - if (i == 0) - indent = origIndent; - break; - default : - if (ch > 31) - { - if (delimiters.indexOf(ch) != -1) - { - addTok(targetBuf, tokBuf, out); - tokBuf.setLength(0); - tokBuf.append(ch); - } - else if (stickyDelimiters.indexOf(ch) != -1) - { - tokBuf.append(ch); - addTok(targetBuf, tokBuf, out); - tokBuf.setLength(0); - } - else - tokBuf.append(ch); - } - break; - } - } - } - } - } - - if (tokBuf.length() > 0) - addTok(targetBuf, tokBuf, out); - - String lastLine = targetBuf.toString().trim(); - - if (lastLine.length() > 0) - out.println(indent, lastLine); - } - /** - * Sets the set of delimiters; default set is "(+". - *

- * Each character represents one delimiter. If a line is ready to be - * word-wrapped and a delimiter is encountered, the delimiter will - * appear as the first character on the following line. - * A quotation mark, " or ', opening a string - * is always a delimiter, whether you specify it or not. - * - * @param newDelimiters the new set of delimiters. - * @see #getDelimiters - */ - public void setDelimiters(String newDelimiters) - { - delimiters = newDelimiters; - } - /** - * Sets the size of the indentation step; default size is 2. - *

- * This is the number of spaces that lines will be indented (when appropriate). - * - * @param newIndentationStep the new size of the indentation step. - * @see #getIndentationStep - */ - public void setIndentationStep(int newIndentationStep) - { - indentationStep = (newIndentationStep < 0 ? 0 : newIndentationStep); - } - /** - * Sets the (desired) maximum line length; default length is - * 74. - *

- * If a token is longer than the requested maximum line length, - * then the line containing that token will obviously be longer - * than the desired maximum. - * - * @param newMaxLineLength the new maximum line length. - * @see #getMaxLineLength - */ - public void setMaxLineLength(int newMaxLineLength) - { - maxLineLength = (newMaxLineLength < 0 ? 0 : newMaxLineLength); - } - /** - * Sets the set of sticky delimiters; default set is ",". - *

- * Each character represents one sticky delimiter. If a line is ready - * to be word-wrapped and a sticky delimiter is encountered, the sticky - * delimiter will appear as the last character on the current line. - * A quotation mark, " or ', closing a string - * is always a sticky delimiter, whether you specify it or not. - * - * @param newStickyDelimiters the new set of sticky delimiters. - * @see #getStickyDelimiters - */ - public void setStickyDelimiters(String newStickyDelimiters) - { - stickyDelimiters = newStickyDelimiters; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapter.java deleted file mode 100644 index d5faaf2fd..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapter.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event; - -/** - * EventAdapter is the interface that all event adapters must - * implement in order to work with the automatic event adapter generation - * model. This interface requires that the adapter implement a method - * that allows setting the event processor delegated to process the event - * after the adapter has received the event from the event source. The - * task of any event adapter is to receive the event and then delegate it - * to the event processor assigned to it, using either - * eventProcessor.processEvent or eventProcessor.processExceptionableEvent. - * - * @author Sanjiva Weerawarana - * @author Matthew J. Duftler - * @see EventProcessor - */ -public interface EventAdapter { - public void setEventProcessor (EventProcessor eventProcessor); -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterImpl.java b/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterImpl.java deleted file mode 100644 index 5d2297388..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event; - -/** - * EventAdapterImpl is a default implementation of the EventAdapter - * interface that specific event adapters may choose to subclass from - * instead of implementing the interface themselves. Saves 5 lines of code - * mebbe. - * - * @author Sanjiva Weerawarana - * @author Matthew J. Duftler - * @see EventAdapter - */ -public class EventAdapterImpl implements EventAdapter { - protected EventProcessor eventProcessor; - - public void setEventProcessor (EventProcessor eventProcessor) { - this.eventProcessor = eventProcessor; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterRegistry.java b/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterRegistry.java deleted file mode 100644 index 1c9d6a7e9..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/EventAdapterRegistry.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event; - -import java.util.Hashtable; - -import com.volmit.iris.util.bsf.util.event.generator.EventAdapterGenerator; - -/** - * The EventAdapterRegistry is the registry of event adapters. - * If a desired adapter is not found, the adapter will be dynamically - * generated when lookup is attempted. Set the dynamic property - * to false to disable this feature. - *

- * This implementation first looks for an adapter in its lookup table - * and if it doesn't find one looks for a standard implementation of - * that adapter in the com.volmit.iris.util.bsf.util.event.adapters package with a - * standard naming convention. The naming convention it assumes is the - * following: for event listener type a.b.c.FooListener, - * it loads an adapter of type - * com.volmit.iris.util.bsf.util.event.adapters.a_b_c_FooAdapter. - * If both the loading and the dynamic generation fail, then a - * null is returned. - *

- * - * @author Sanjiva Weerawarana - * @author Matthew J. Duftler - * @see EventAdapter - */ -public class EventAdapterRegistry { - private static Hashtable reg = new Hashtable (); - private static ClassLoader cl = null; - private static String adapterPackage = "com.volmit.iris.util.bsf.util.event.adapters"; - private static String adapterSuffix = "Adapter"; - private static boolean dynamic = true; - - public static Class lookup (Class listenerType) { - String key = listenerType.getName().replace ('.', '_'); - Class adapterClass = (Class) reg.get (key); - - if (adapterClass == null) { - String en = key.substring (0, key.lastIndexOf ("Listener")); - String cn = adapterPackage + "." + en + adapterSuffix; - - try { - // Try to resolve one. - // adapterClass = (cl != null) ? cl.loadClass (cn) : Class.forName (cn); - adapterClass = (cl != null) ? cl.loadClass (cn) - : Thread.currentThread().getContextClassLoader().loadClass (cn); // rgf, 2006-01-05 - - } catch (ClassNotFoundException e) { - if (dynamic) { - // Unable to resolve one, try to generate one. - adapterClass = // if second argument is set to 'true', then the class file will be stored in the filesystem - EventAdapterGenerator.makeEventAdapterClass (listenerType, false); - } - } - - if (adapterClass != null) { - reg.put (key, adapterClass); - } - } - - return adapterClass; - } - public static void register (Class listenerType, Class eventAdapterClass) { - String key = listenerType.getName().replace('.', '_'); - reg.put (key, eventAdapterClass); - } - /** - * Class loader to use to load event adapter classes. - */ - public static void setClassLoader (ClassLoader cloader) { - cl = cloader; - } - /** - * Indicates whether or not to dynamically generate adapters; default is - * true. - *

- * If the dynamic property is set to true, and the - * ClassLoader is unable to resolve an adapter, one will be - * dynamically generated. - * - * @param dynamic whether or not to dynamically generate adapters. - */ - public static void setDynamic (boolean dynamic) { - EventAdapterRegistry.dynamic = dynamic; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/EventProcessor.java b/src/main/java/com/volmit/iris/util/bsf/util/event/EventProcessor.java deleted file mode 100644 index 7b5db8ac7..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/EventProcessor.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event; - - -/** - * EventProcessor is the interface that event adapters use to - * delegate events they received to be delivered to the appropriate target. - * They can simply deliver the event using processEvent or, if the event - * can be excepted to, via processExceptionableEvent (in which case the - * adapter is expected to forward on an exception to the source bean). - * - * @author Sanjiva Weerawarana - * @author Matthew J. Duftler - * @see EventAdapter - */ -public interface EventProcessor { - public void processEvent (String filter, Object[] eventInfo); - public void processExceptionableEvent (String filter, Object[] eventInfo) - throws Exception; -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ActionAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ActionAdapter.java deleted file mode 100644 index 2ff05d93e..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ActionAdapter.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_awt_event_ActionAdapter extends EventAdapterImpl - implements ActionListener { - - public void actionPerformed (ActionEvent e) { - eventProcessor.processEvent ("actionPerformed", new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_AdjustmentAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_AdjustmentAdapter.java deleted file mode 100644 index b19e2092e..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_AdjustmentAdapter.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.awt.event.AdjustmentEvent; -import java.awt.event.AdjustmentListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_awt_event_AdjustmentAdapter extends EventAdapterImpl - implements AdjustmentListener { - - public void adjustmentValueChanged (AdjustmentEvent e) { - eventProcessor.processEvent ("adjustmentValueChanged", new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ComponentAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ComponentAdapter.java deleted file mode 100644 index 2d5a0add4..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ComponentAdapter.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_awt_event_ComponentAdapter extends EventAdapterImpl - implements ComponentListener { - - public void componentHidden (ComponentEvent e) { - eventProcessor.processEvent ("componentHidden", new Object[]{e}); - } - public void componentMoved (ComponentEvent e) { - eventProcessor.processEvent ("componentMoved", new Object[]{e}); - } - public void componentResized (ComponentEvent e) { - eventProcessor.processEvent ("componentResized", new Object[]{e}); - } - public void componentShown (ComponentEvent e) { - eventProcessor.processEvent ("componentShown", new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ContainerAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ContainerAdapter.java deleted file mode 100644 index 74c935d5b..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ContainerAdapter.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.awt.event.ContainerEvent; -import java.awt.event.ContainerListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_awt_event_ContainerAdapter extends EventAdapterImpl - implements ContainerListener { - - public void componentAdded (ContainerEvent e) { - eventProcessor.processEvent ("componentAdded", new Object[]{e}); - } - public void componentRemoved (ContainerEvent e) { - eventProcessor.processEvent ("componentRemoved", new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_FocusAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_FocusAdapter.java deleted file mode 100644 index a7740188d..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_FocusAdapter.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_awt_event_FocusAdapter extends EventAdapterImpl - implements FocusListener { - - public void focusGained (FocusEvent e) { - eventProcessor.processEvent ("focusGained", new Object[]{e}); - } - public void focusLost (FocusEvent e) { - eventProcessor.processEvent ("focusLost", new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ItemAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ItemAdapter.java deleted file mode 100644 index 9f7508110..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_ItemAdapter.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_awt_event_ItemAdapter extends EventAdapterImpl - implements ItemListener { - - public void itemStateChanged (ItemEvent e) { - eventProcessor.processEvent ("itemStateChanged", new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_KeyAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_KeyAdapter.java deleted file mode 100644 index 21c3a7e2c..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_KeyAdapter.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_awt_event_KeyAdapter extends EventAdapterImpl - implements KeyListener { - - public void keyPressed (KeyEvent e) { - eventProcessor.processEvent ("keyPressed", new Object[]{e}); - } - public void keyReleased (KeyEvent e) { - eventProcessor.processEvent ("keyReleased", new Object[]{e}); - } - public void keyTyped (KeyEvent e) { - eventProcessor.processEvent ("keyTyped", new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseAdapter.java deleted file mode 100644 index a0ec4950f..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseAdapter.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_awt_event_MouseAdapter extends EventAdapterImpl - implements MouseListener { - - public void mouseClicked (MouseEvent e) { - eventProcessor.processEvent ("mouseClicked", new Object[]{e}); - } - public void mouseEntered (MouseEvent e) { - eventProcessor.processEvent ("mouseEntered", new Object[]{e}); - } - public void mouseExited (MouseEvent e) { - eventProcessor.processEvent ("mouseExited", new Object[]{e}); - } - public void mousePressed (MouseEvent e) { - eventProcessor.processEvent ("mousePressed", new Object[]{e}); - } - public void mouseReleased (MouseEvent e) { - eventProcessor.processEvent ("mouseReleased", new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseMotionAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseMotionAdapter.java deleted file mode 100644 index ec80769e3..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_MouseMotionAdapter.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.awt.event.MouseEvent; -import java.awt.event.MouseMotionListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_awt_event_MouseMotionAdapter extends EventAdapterImpl - implements MouseMotionListener { - - public void mouseDragged(MouseEvent e) { - eventProcessor.processEvent ("mouseDragged", new Object[]{e}); - } - public void mouseMoved(MouseEvent e) { - eventProcessor.processEvent ("mouseMoved", new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_TextAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_TextAdapter.java deleted file mode 100644 index f0ab8010a..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_TextAdapter.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.awt.event.TextEvent; -import java.awt.event.TextListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_awt_event_TextAdapter extends EventAdapterImpl - implements TextListener { - - public void textValueChanged (TextEvent e) { - eventProcessor.processEvent ("textValueChanged", new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_WindowAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_WindowAdapter.java deleted file mode 100644 index 866387eb3..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_awt_event_WindowAdapter.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_awt_event_WindowAdapter extends EventAdapterImpl - implements WindowListener { - - public void windowActivated (WindowEvent e) { - eventProcessor.processEvent ("windowActivated", new Object[]{e}); - } - public void windowClosed (WindowEvent e) { - eventProcessor.processEvent ("windowClosed", new Object[]{e}); - } - public void windowClosing (WindowEvent e) { - eventProcessor.processEvent ("windowClosing", new Object[]{e}); - } - public void windowDeactivated (WindowEvent e) { - eventProcessor.processEvent ("windowDeactivated", new Object[]{e}); - } - public void windowDeiconified (WindowEvent e) { - eventProcessor.processEvent ("windowDeiconified", new Object[]{e}); - } - public void windowIconified (WindowEvent e) { - eventProcessor.processEvent ("windowIconified", new Object[]{e}); - } - public void windowOpened (WindowEvent e) { - eventProcessor.processEvent ("windowOpened", new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_PropertyChangeAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_PropertyChangeAdapter.java deleted file mode 100644 index 9adbf4884..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_PropertyChangeAdapter.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_beans_PropertyChangeAdapter extends EventAdapterImpl - implements PropertyChangeListener { - - public void propertyChange(PropertyChangeEvent e) { - eventProcessor.processEvent (e.getPropertyName(), new Object[]{e}); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_VetoableChangeAdapter.java b/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_VetoableChangeAdapter.java deleted file mode 100644 index aafa64a98..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/adapters/java_beans_VetoableChangeAdapter.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.adapters; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyVetoException; -import java.beans.VetoableChangeListener; - -import com.volmit.iris.util.bsf.util.event.EventAdapterImpl; - -public class java_beans_VetoableChangeAdapter extends EventAdapterImpl - implements VetoableChangeListener { - - public void vetoableChange (PropertyChangeEvent e) throws PropertyVetoException { - try - { - eventProcessor.processExceptionableEvent (e.getPropertyName(), new Object[]{e}); - } - catch (PropertyVetoException ex) - { - throw ex; - } - catch (Exception ex) - { - } - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/AdapterClassLoader.java b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/AdapterClassLoader.java deleted file mode 100644 index 59dec6c66..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/AdapterClassLoader.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.generator; - -import java.util.Hashtable; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class AdapterClassLoader extends ClassLoader -{ - private static Hashtable classCache = new Hashtable(); - private Class c; - - private Log logger = LogFactory.getLog(this.getClass().getName()); - - public AdapterClassLoader() - { - super(); - } - public synchronized Class defineClass(String name, byte[] b) - { - if ((c = getLoadedClass(name)) == null) - { - c = defineClass(name.replace('/','.'), b, 0, b.length); // rgf, 2006-02-03 - put(name, c); - } - else - { - logger.error("AdapterClassLoader: " + c + - " previously loaded. Can not redefine class."); - } - - return c; - } - final protected Class findClass(String name) - { - return get(name); - } - final protected Class get(String name) - { - return (Class)classCache.get(name); - } - public synchronized Class getLoadedClass(String name) - { - Class c = findLoadedClass(name); - - if (c == null) - { - try - { - c = findSystemClass(name); - } - catch (ClassNotFoundException e) - { - } - } - - if (c == null) - { - c = findClass(name); - } - - return c; - } - protected synchronized Class loadClass(String name, boolean resolve) - throws ClassNotFoundException - { - Class c = getLoadedClass(name); - - if (c != null && resolve) - { - resolveClass(c); - } - - return c; - } - // Not in JDK 1.1, only in JDK 1.2. -// public AdapterClassLoader(ClassLoader loader) -// { -// super(loader); -// } - - final protected void put(String name, Class c) - { - classCache.put(name, c); - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/ByteUtility.java b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/ByteUtility.java deleted file mode 100644 index 1412696cf..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/ByteUtility.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.generator; - -/** - * Byte handling utilities - * - * 5 April 1999 - functions to append standard types to byte arrays - * functions to produce standard types from byte arrays - * - * @author Richard F. Boehme - * - */ -public class ByteUtility -{ - public static byte[] addBytes(byte[] array,byte[] value) - { - if( null != array ) - { - byte newarray[] = new byte[array.length + value.length]; - System.arraycopy(array,0,newarray,0,array.length); - System.arraycopy(value,0,newarray,array.length,value.length); - array = newarray; - } - else - { - array = value; - } - return array; - } - public static byte[] addBytes(byte[] array, byte value) - { - if( null != array ) - { - byte newarray[] = new byte[array.length + 1]; - System.arraycopy(array,0,newarray,0,array.length); - newarray[newarray.length-1] = value; - array = newarray; - } - else - { - array = new byte[1]; - array[0] = value; - } - return array; - } - public static byte[] addBytes(byte[] array, int value) - { - if( null != array ) - { - byte newarray[] = new byte[array.length + 3]; - System.arraycopy(array,0,newarray,0,array.length); - newarray[newarray.length-3] = (byte) (( value >> 16 ) & 0xFF); - newarray[newarray.length-2] = (byte) (( value >> 8 ) & 0xFF); - newarray[newarray.length-1] = (byte) ( value & 0xFF); - array = newarray; - } - else - { - array = new byte[3]; - array[0] = (byte) (( value >> 16 ) & 0xFF); - array[1] = (byte) (( value >> 8 ) & 0xFF); - array[2] = (byte) ( value & 0xFF); - } - return array; - } - public static byte[] addBytes(byte[] array, long value) - { - if( null != array ) - { - byte newarray[] = new byte[array.length + 4]; - System.arraycopy(array,0,newarray,0,array.length); - newarray[newarray.length-4] = (byte) (( value >> 24 ) & 0xFF); - newarray[newarray.length-3] = (byte) (( value >> 16 ) & 0xFF); - newarray[newarray.length-2] = (byte) (( value >> 8 ) & 0xFF); - newarray[newarray.length-1] = (byte) ( value & 0xFF); - array = newarray; - } - else - { - array = new byte[4]; - array[0] = (byte) (( value >> 24 ) & 0xFF); - array[1] = (byte) (( value >> 16 ) & 0xFF); - array[2] = (byte) (( value >> 8 ) & 0xFF); - array[3] = (byte) (value & 0xFF); - } - return array; - } - public static byte[] addBytes(byte[] array,String value) - { - if( null != value ) - { - if( null != array) - { - byte newarray[] = new byte[array.length + value.length()]; - System.arraycopy(array,0,newarray,0,array.length); - System.arraycopy(value.getBytes(),0,newarray,array.length,value.length()); - array = newarray; - } - else - { - array = value.getBytes(); - } - } - return array; - } - public static byte[] addBytes(byte[] array, short value) - { - if( null != array) - { - byte newarray[] = new byte[array.length + 2]; - System.arraycopy(array,0,newarray,0,array.length); - newarray[newarray.length-2] = (byte) (( value >> 8 ) & 0xFF); - newarray[newarray.length-1] = (byte) ( value & 0xFF); - array = newarray; - } - else - { - array = new byte[2]; - array[0] = (byte) (( value >> 8 ) & 0xFF); - array[1] = (byte) ( value & 0xFF); - } - return array; - } - public static double byteArrayToDouble(byte high[], byte low[]) - { - double temp = 0; - // high bytes - temp += (((long)high[0]) & 0xFF) << 56; - temp += (((long)high[1]) & 0xFF) << 48; - temp += (((long)high[2]) & 0xFF) << 40; - temp += (((long)high[3]) & 0xFF) << 32; - // low bytes - temp += (((long)low[0]) & 0xFF) << 24; - temp += (((long)low[1]) & 0xFF) << 16; - temp += (((long)low[2]) & 0xFF) << 8; - temp += (((long)low[3]) & 0xFF); - return temp; - } - public static double byteArrayToDouble(byte value[]) - { - byte high[] = new byte[4]; - byte low[] = new byte[4]; - high[0] = value[0]; - high[1] = value[1]; - high[2] = value[2]; - high[3] = value[3]; - low[0] = value[4]; - low[1] = value[5]; - low[2] = value[6]; - low[3] = value[7]; - return byteArrayToDouble(high,low); - } - public static float byteArrayToFloat(byte value[]) - { - float temp = 0; - temp += (((int)value[0]) & 0xFF) << 24; - temp += (((int)value[1]) & 0xFF) << 16; - temp += (((int)value[2]) & 0xFF) << 8; - temp += (((int)value[3]) & 0xFF); - return temp; - } - public static int byteArrayToInt(byte value[]) - { - int temp = 0; - temp += (((int)value[0]) & 0xFF) << 24; - temp += (((int)value[1]) & 0xFF) << 16; - temp += (((int)value[2]) & 0xFF) << 8; - temp += (((int)value[3]) & 0xFF); - return temp; - } - public static long byteArrayToLong(byte value[]) - { - byte high[] = new byte[4]; - byte low[] = new byte[4]; - high[0] = value[0]; - high[1] = value[1]; - high[2] = value[2]; - high[3] = value[3]; - low[0] = value[4]; - low[1] = value[5]; - low[2] = value[6]; - low[3] = value[7]; - return byteArrayToLong(high,low); - } - public static long byteArrayToLong(byte high[], byte low[]) - { - long temp = 0; - // high bytes - temp += (((long)high[0]) & 0xFF) << 56; - temp += (((long)high[1]) & 0xFF) << 48; - temp += (((long)high[2]) & 0xFF) << 40; - temp += (((long)high[3]) & 0xFF) << 32; - // low bytes - temp += (((long)low[0]) & 0xFF) << 24; - temp += (((long)low[1]) & 0xFF) << 16; - temp += (((long)low[2]) & 0xFF) << 8; - temp += (((long)low[3]) & 0xFF); - return temp; - } - // make the following loops with check on array length ***************** - public static short byteArrayToShort(byte value[]) - { - short temp = 0; - temp += (((int)value[0]) & 0xFF) << 8; - temp += (((int)value[1]) & 0xFF); - return temp; - } - public static String byteToHexString(byte value) - { - String temp = null; - - switch( (value & 0xF0) >> 4 ) - { - case 0: - temp = "0"; - break; - case 1: - temp = "1"; - break; - case 2: - temp = "2"; - break; - case 3: - temp = "3"; - break; - case 4: - temp = "4"; - break; - case 5: - temp = "5"; - break; - case 6: - temp = "6"; - break; - case 7: - temp = "7"; - break; - case 8: - temp = "8"; - break; - case 9: - temp = "9"; - break; - case 10: - temp = "A"; - break; - case 11: - temp = "B"; - break; - case 12: - temp = "C"; - break; - case 13: - temp = "D"; - break; - case 14: - temp = "E"; - break; - case 15: - temp = "F"; - break; - } - switch( (value & 0x0F) ) - { - case 0: - temp += "0"; - break; - case 1: - temp += "1"; - break; - case 2: - temp += "2"; - break; - case 3: - temp += "3"; - break; - case 4: - temp += "4"; - break; - case 5: - temp += "5"; - break; - case 6: - temp += "6"; - break; - case 7: - temp += "7"; - break; - case 8: - temp += "8"; - break; - case 9: - temp += "9"; - break; - case 10: - temp += "A"; - break; - case 11: - temp += "B"; - break; - case 12: - temp += "C"; - break; - case 13: - temp += "D"; - break; - case 14: - temp += "E"; - break; - case 15: - temp += "F"; - break; - } - return temp; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/Bytecode.java b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/Bytecode.java deleted file mode 100644 index f89846113..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/Bytecode.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.generator; - -/** - * Bytecode handling utilities - * - * Handle standard byte arrays as defined in Java VM and Class File - * - * 5 April 1999 - functions to append Class File byte subarrays - * into a Class File byte array - * - * @author Richard F. Boehme - * - */ -public class Bytecode -{ - // Constant Pool Item Codes - public static final byte C_Utf8 = 0x01; // 1 - public static final byte C_Integer = 0x03; // 3 - public static final byte C_Float = 0x04; // 4 - public static final byte C_Long = 0x05; // 5 - public static final byte C_Double = 0x06; // 6 - public static final byte C_Class = 0x07; // 7 - public static final byte C_String = 0x08; // 8 - public static final byte C_FieldRef = 0x09; // 9 - public static final byte C_MethodRef = 0x0A; // 10 - public static final byte C_InterfaceMethodRef = 0x0B; // 11 - public static final byte C_NameAndType = 0x0C; // 12 - -//public static byte[] addDouble(byte[] array,double value) -//{ -// array = ByteUtility.addBytes(array,C_Double); -// array = ByteUtility.addBytes(array,value); -// return array; -//} - - public static byte[] addClass(byte[] array,short value) - { return addRef(C_Class,array,value); } - public static byte[] addFieldRef(byte[] array,short value1,short value2) - { return addRef(C_FieldRef,array,value1,value2); } - public static byte[] addInteger(byte[] array,int value) - { - array = ByteUtility.addBytes(array,C_Integer); - array = ByteUtility.addBytes(array,value); - return array; - } - public static byte[] addInterfaceMethodRef(byte[] array,short value1,short value2) - { return addRef(C_InterfaceMethodRef,array,value1,value2); } -//public static byte[] addFloat(byte[] array,float value) -//{ -// array = ByteUtility.addBytes(array,C_Float); -// array = ByteUtility.addBytes(array,value); -// return array; -//} - - public static byte[] addLong(byte[] array,long value) - { - array = ByteUtility.addBytes(array,C_Long); - array = ByteUtility.addBytes(array,value); - return array; - } - public static byte[] addMethodRef(byte[] array,short value1,short value2) - { return addRef(C_MethodRef,array,value1,value2); } - public static byte[] addNameAndType(byte[] array,short value1,short value2) - { return addRef(C_NameAndType,array,value1,value2); } - public static byte[] addRef(byte refType,byte[] array,short value) - { - array = ByteUtility.addBytes(array,refType); - array = ByteUtility.addBytes(array,value); - return array; - } - // Generic Bytecode Methods - public static byte[] addRef(byte refType,byte[] array,short value1,short value2) - { - array = ByteUtility.addBytes(array,refType); - array = ByteUtility.addBytes(array,value1); - array = ByteUtility.addBytes(array,value2); - return array; - } - public static byte[] addString(byte[] array,short value) - { return addRef(C_String,array,value); } - // Constant Pool Item Methods - public static byte[] addUtf8(byte[] array,String value) - { - array = ByteUtility.addBytes(array,C_Utf8); - array = ByteUtility.addBytes(array,(short)value.length()); - array = ByteUtility.addBytes(array,value); - return array; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/EventAdapterGenerator.java b/src/main/java/com/volmit/iris/util/bsf/util/event/generator/EventAdapterGenerator.java deleted file mode 100644 index c38dcbe74..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/event/generator/EventAdapterGenerator.java +++ /dev/null @@ -1,568 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.event.generator; - -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** EventAdapterGenerator - * - * Generate an "Event Adapter" dynamically during program execution - * - **/ -public class EventAdapterGenerator -{ - public static AdapterClassLoader ldr = new AdapterClassLoader(); - static Class EVENTLISTENER = null; - static String CLASSPACKAGE = "org/apache/bsf/util/event/adapters/"; - static String WRITEDIRECTORY = null; - - // starting 8 bytes of all Java Class files - static byte CLASSHEADER[]; - // constant pool items found in all event adapters - static short BASECPCOUNT; // number of cp items + 1 ( cp item # 0 reserved for JVM ) - static byte BASECP[]; // - // some bytes in the middle of the class file (see below) - static byte FIXEDCLASSBYTES[]; - // the initialization method, noargs constructor - static byte INITMETHOD[]; - - private static Log logger; - - /* The static initializer */ - static - { - logger = LogFactory.getLog( - (com.volmit.iris.util.bsf.util.event.generator.EventAdapterGenerator.class).getName()); - - String USERCLASSPACKAGE = System.getProperty("DynamicEventClassPackage", - ""); - - if (!USERCLASSPACKAGE.equals("")) - { - CLASSPACKAGE = USERCLASSPACKAGE; - } - - if(CLASSPACKAGE.length() > 0 ) - { - CLASSPACKAGE = CLASSPACKAGE.replace('\\','/'); - if(!CLASSPACKAGE.endsWith("/")) - { CLASSPACKAGE = CLASSPACKAGE+"/"; } - } - WRITEDIRECTORY = System.getProperty("DynamicEventClassWriteDirectory",CLASSPACKAGE); - if(WRITEDIRECTORY.length() > 0 ) - { - WRITEDIRECTORY = WRITEDIRECTORY.replace('\\','/'); - if(!WRITEDIRECTORY.endsWith("/")) - { WRITEDIRECTORY = WRITEDIRECTORY+"/"; } - } - try - // { EVENTLISTENER = Class.forName("java.util.EventListener"); } - { EVENTLISTENER = Thread.currentThread().getContextClassLoader().loadClass ("java.util.EventListener"); } // rgf, 2006-01-05 - catch(ClassNotFoundException ex) - { - System.err.println(ex.getMessage()); - ex.printStackTrace(); - } - - - // start of the Java Class File - CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xCA); // magic - CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xFE); // magic - CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xBA); // magic - CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xBE); // magic - CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(short)3); // minor version - CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(short)45); // major version - - // Start the constant pool for base items in all event adapter classes - BASECPCOUNT = 17; // number of cp items + 1 ( cp item # 0 reserved for JVM ) - - // cp item 01 - BASECP = Bytecode.addUtf8(BASECP,"()V"); - - // cp item 02 - BASECP = Bytecode.addUtf8(BASECP,""); - - // cp item 03 - BASECP = Bytecode.addUtf8(BASECP,"Code"); - - // cp item 04 - BASECP = Bytecode.addUtf8(BASECP,"eventProcessor"); - - // cp item 05 - BASECP = Bytecode.addUtf8(BASECP,"java/lang/Object"); - - // cp item 06 - BASECP = Bytecode.addUtf8(BASECP,"org/apache/bsf/util/event/EventAdapterImpl"); - - // cp item 07 - BASECP = Bytecode.addUtf8(BASECP,"org/apache/bsf/util/event/EventProcessor"); - - // cp item 08 - BASECP = Bytecode.addUtf8(BASECP,"(Ljava/lang/String;[Ljava/lang/Object;)V"); - - // cp item 09 - BASECP = Bytecode.addUtf8(BASECP,"Lorg/apache/bsf/util/event/EventProcessor;"); - - // cp item 10 - BASECP = Bytecode.addClass(BASECP,(short)5); // Class "java/lang/Object" - - // cp item 11 - BASECP = Bytecode.addClass(BASECP,(short)6); // Class "org/apache/bsf/util/event/EventAdapterImpl" - - // cp item 12 - BASECP = Bytecode.addClass(BASECP,(short)7); // Class "org/apache/bsf/util/event/EventProcessor" - - // cp item 13 - BASECP = Bytecode.addNameAndType(BASECP,(short)2,(short)1); // "" "()V" - - // cp item 14 - BASECP = Bytecode.addNameAndType(BASECP,(short)4,(short)9); // "eventProcessor" "Lorg/apache/bsf/util/event/EventProcessor;" - - // cp item 15 - BASECP = Bytecode.addFieldRef(BASECP,(short)11,(short)14); - - // cp item 16 - BASECP = Bytecode.addMethodRef(BASECP,(short)11,(short)13); - - // fixed bytes in middle of class file - FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)0x21); // access_flags (fixed) - FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)20); // this_class (fixed) - FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)11); // super_class (fixed) - FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)1); // interface_count (fixed) - FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)19); // interfaces (fixed) - FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)0); // field_count (fixed) - - // initialization method, constructor - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1); // access_flags - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)2); // name_index "" - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1); // descriptor_index "()V" - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1); // attribute_count - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)3); // attribute_name_index "Code" - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(long)17); // attribute_length - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1); // max_stack - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1); // max_locals - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(long)5); // code_length - //code - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(byte)0x2A); // aload_0 - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(byte)0xB7); // invokespecial - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)16); // method_ref index - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(byte)0xB1); // return - // exception table - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)0); // exception_table_length - INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)0); // attributes_count - - } - - /* methods that take an EventListener Class Type to create an EventAdapterClass */ - public static Class makeEventAdapterClass(Class listenerType,boolean writeClassFile) - { - logger.info("EventAdapterGenerator"); - - if( EVENTLISTENER.isAssignableFrom(listenerType) ) - { - boolean exceptionable = false; - boolean nonExceptionable = false; - byte constantPool[] = null; - short cpBaseIndex; - short cpCount = 0; - short cpExceptionBaseIndex; - short exceptionableCount; - short nonExceptionableCount; - - /* Derive Names */ - String listenerTypeName = listenerType.getName(); - logger.info("ListenerTypeName: "+listenerTypeName); - String adapterClassName = - CLASSPACKAGE+ - (listenerTypeName.endsWith("Listener") - ? listenerTypeName.substring(0, listenerTypeName.length() - 8) - : listenerTypeName).replace('.', '_') + - "Adapter"; - String finalAdapterClassName = adapterClassName; - Class cached = null; - int suffixIndex = 0; - - do - { - if (null != (cached = ldr.getLoadedClass(finalAdapterClassName))) - { - logger.info("cached: "+cached); - try - { - if (!listenerType.isAssignableFrom(cached)) - finalAdapterClassName = adapterClassName + "_" + suffixIndex++; - else - return cached; - } - catch(VerifyError ex) - { - System.err.println(ex.getMessage()); - ex.printStackTrace(); - return cached; - } - } - } - while (cached != null); - - String eventListenerName = listenerTypeName.replace('.', '/'); - - /* method stuff */ - java.lang.reflect.Method lms[] = listenerType.getMethods(); - - /* ****************************************************************************************** */ - // Listener interface - // Class name - cpCount += 4; - - // cp item 17 - constantPool = Bytecode.addUtf8(constantPool,eventListenerName); - - // cp item 18 - constantPool = Bytecode.addUtf8(constantPool,finalAdapterClassName); - - // cp item 19 - constantPool = Bytecode.addClass(constantPool,(short)17); - - // cp item 20 - constantPool = Bytecode.addClass(constantPool,(short)18); - - // do we have nonExceptionalble event, exceptionable or both - for (int i = 0 ; i < lms.length ; ++i) - { - Class exceptionTypes[] = lms[i].getExceptionTypes(); - if( 0 < exceptionTypes.length) - { exceptionable = true; } - else - { nonExceptionable = true; } - }/* End for*/ - - /* ****************************************************************************************** */ - // optional inclusion of nonexceptional events affects exceptional events indices - - nonExceptionableCount = 0; - if(nonExceptionable) - { - nonExceptionableCount = 3; - cpCount += nonExceptionableCount; - - // cp item 21 - constantPool = Bytecode.addUtf8(constantPool,"processEvent"); - - // cp item 22 - constantPool = Bytecode.addNameAndType(constantPool,(short)21,(short)8); - - - // cp item 23 - constantPool = Bytecode.addInterfaceMethodRef(constantPool,(short)12,(short)22); - } - - /* ****************************************************************************************** */ - // optional inclusion of exceptional events affects CP Items which follow for specific methods - - exceptionableCount = 0; - if(exceptionable) - { - int classIndex = BASECPCOUNT + cpCount + 1; - int nameIndex = BASECPCOUNT + cpCount + 0; - int natIndex = BASECPCOUNT + cpCount + 3; - - exceptionableCount = 5; - cpCount += exceptionableCount; - - // cp item 24 or 21 - constantPool = Bytecode.addUtf8(constantPool,"processExceptionableEvent"); - - // cp item 25 or 22 - constantPool = Bytecode.addUtf8(constantPool,"java/lang/Exception"); - - // cp item 26 or 23 - constantPool = Bytecode.addClass(constantPool,(short)classIndex); - - // cp item 27 or 24 - constantPool = Bytecode.addNameAndType(constantPool,(short)nameIndex,(short)8); - - // cp item 28 or 25 - constantPool = Bytecode.addInterfaceMethodRef(constantPool,(short)12,(short)natIndex); - - } - - // base index for method cp references - cpBaseIndex = (short)(BASECPCOUNT + cpCount); - logger.debug("cpBaseIndex: " + cpBaseIndex); - - for (int i = 0 ; i < lms.length ; ++i) - { - String eventMethodName = lms[i].getName(); - String eventName = lms[i].getParameterTypes()[0].getName().replace('.','/'); - cpCount += 3; - // cp items for event methods - constantPool = Bytecode.addUtf8(constantPool,eventMethodName); - constantPool = Bytecode.addUtf8(constantPool,("(L" + eventName + ";)V")); - constantPool = Bytecode.addString(constantPool,(short)(BASECPCOUNT+cpCount-3)); - }/* End for*/ - - boolean propertyChangeFlag[] = new boolean[lms.length]; - int cpIndexPCE = 0; - for (int i = 0 ; i < lms.length ; ++i) - { - String eventName = lms[i].getParameterTypes()[0].getName().replace('.','/'); - // cp items for PropertyChangeEvent special handling - if(eventName.equalsIgnoreCase("java/beans/PropertyChangeEvent")) - { - propertyChangeFlag[i] = true; - if( 0 == cpIndexPCE ) - { - constantPool = Bytecode.addUtf8(constantPool,eventName); - constantPool = Bytecode.addUtf8(constantPool,"getPropertyName"); - constantPool = Bytecode.addUtf8(constantPool,"()Ljava/lang/String;"); - constantPool = Bytecode.addClass(constantPool,(short)(BASECPCOUNT + cpCount)); - constantPool = Bytecode.addNameAndType(constantPool, - (short)(BASECPCOUNT + cpCount + 1), - (short)(BASECPCOUNT + cpCount + 2)); - constantPool = Bytecode.addMethodRef(constantPool, - (short)(BASECPCOUNT + cpCount + 3), - (short)(BASECPCOUNT + cpCount + 4)); - cpCount += 6; - cpIndexPCE = BASECPCOUNT + cpCount - 1; - - } - } - else - { propertyChangeFlag[i] = false; } - }/* End for*/ - - cpExceptionBaseIndex = (short)(BASECPCOUNT + cpCount); - logger.debug("cpExceptionBaseIndex: " + cpExceptionBaseIndex); - - int excpIndex[][] = new int[lms.length][]; - for (int i = 0 ; i < lms.length ; ++i) - { - Class exceptionTypes[] = lms[i].getExceptionTypes(); - excpIndex[i] = new int[exceptionTypes.length]; - for ( int j = 0 ; j < exceptionTypes.length ; j++) - { - constantPool = Bytecode.addUtf8(constantPool,exceptionTypes[j].getName().replace('.', '/')); - constantPool = Bytecode.addClass(constantPool,(short)(BASECPCOUNT+cpCount)); - excpIndex[i][j] = BASECPCOUNT + cpCount + 1; - cpCount += 2; - } - }/* End for*/ - /* end constant pool */ - - /* ************************************************************************************************ */ - // put the Class byte array together - - /* start */ - byte newClass[] = CLASSHEADER; // magic, version (fixed) - short count = (short)(BASECPCOUNT + cpCount); - newClass = ByteUtility.addBytes(newClass,count); // constant_pool_count (variable) - newClass = ByteUtility.addBytes(newClass,BASECP); // constant_pool (fixed) - newClass = ByteUtility.addBytes(newClass,constantPool); // constant_pool (variable) - newClass = ByteUtility.addBytes(newClass,FIXEDCLASSBYTES); // see FIXEDCLASSBYTES (fixed) - newClass = ByteUtility.addBytes(newClass,(short)(lms.length+1)); // method_count (variable) - newClass = ByteUtility.addBytes(newClass,INITMETHOD); // constructor (fixed) - // methods - - /* ****************************************************************************************** */ - /* loop over listener methods from listenerType */ - for (int i = 0 ; i < lms.length ; ++i) - { - newClass = ByteUtility.addBytes(newClass,(short)1); // access_flags (fixed) - newClass = ByteUtility.addBytes(newClass,(short)(cpBaseIndex+3*i+0)); // name_index (variable) - newClass = ByteUtility.addBytes(newClass,(short)(cpBaseIndex+3*i+1)); // descriptor_index (variable) - newClass = ByteUtility.addBytes(newClass,(short)1); // attribute_count (fixed) - newClass = ByteUtility.addBytes(newClass,(short)3); // attribute_name_index code(fixed) - - // Code Attribute Length - int length = 32; - if( 0 < excpIndex[i].length ) - { length += 5 + 8 * ( 1 + excpIndex[i].length ); } - if(propertyChangeFlag[i]) - { length += 2; } - newClass = ByteUtility.addBytes(newClass,(long)length); // attribute_length (variable) - - // start code attribute - newClass = ByteUtility.addBytes(newClass,(short)6); // max_stack (fixed) - newClass = ByteUtility.addBytes(newClass,(short)3); // max_locals (fixed) - - // Code Length - length = 20; - if(exceptionable && 0 < excpIndex[i].length) - { length += 5; } - if(propertyChangeFlag[i]) - { length += 2; } - newClass = ByteUtility.addBytes(newClass,(long)length); // code_length (variable) - - // start code - newClass = ByteUtility.addBytes(newClass,(byte)0x2A); // aload_0 (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0xB4); // getfield (fixed) - newClass = ByteUtility.addBytes(newClass,(short)15); // index (fixed) - - - if(propertyChangeFlag[i]) - { // the propertyName is passed as the first parameter - newClass = ByteUtility.addBytes(newClass,(byte)0x2B); // aload_1 (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0xB6); // invokevirtual (fixed) - newClass = ByteUtility.addBytes(newClass,(short)cpIndexPCE); // methodref (variable) - } - else - { // the eventMethodName is passed as the first parameter - // Target for method invocation. - newClass = ByteUtility.addBytes(newClass,(byte)0x12); // ldc (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)(cpBaseIndex+3*i+2)); // index (byte) (variable) - } - - newClass = ByteUtility.addBytes(newClass,(byte)0x04); // iconst_1 (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0xBD); // anewarray (fixed) - newClass = ByteUtility.addBytes(newClass,(short)10); // Class java/lang/Object (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0x59); // dup (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0x03); // iconst_0 (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0x2B); // aload_1 (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0x53); // aastore (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0xB9); // invokeinterface (fixed) - - // index to processEvent or processExceptionableEvent method - length = 23; // actually an index into cp - if(exceptionable && nonExceptionable) - { // interface method index - if( 0 < lms[i].getExceptionTypes().length ) - { length += 5; } - } - else if(exceptionable) - { length += 2; } - newClass = ByteUtility.addBytes(newClass,(short)length); // index (process??????...) (variable) - - newClass = ByteUtility.addBytes(newClass,(byte)0x03); // iconst_0 (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0x00); // noop (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0xB1); // return (fixed) - - if(exceptionable && 0 < excpIndex[i].length) - { // exception code - newClass = ByteUtility.addBytes(newClass,(byte)0x4D); // astore_2 (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0x2C); // aload_2 (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0xBF); // athrow (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0x57); // pop (fixed) - newClass = ByteUtility.addBytes(newClass,(byte)0xB1); // return (fixed) - // end code - - // exception table - length = excpIndex[i].length; - newClass = ByteUtility.addBytes(newClass,(short)(1+length)); // exception_table_length (variable) - for( int j = 0 ; j < length ; j++ ) - { // catch exception types and rethrow - newClass = ByteUtility.addBytes(newClass,(short)0); // start_pc (fixed) - if(propertyChangeFlag[i]) - { - newClass = ByteUtility.addBytes(newClass,(short)21); // end_pc (fixed) - newClass = ByteUtility.addBytes(newClass,(short)22); // handler_pc (fixed) - } - else - { - newClass = ByteUtility.addBytes(newClass,(short)19); // end_pc (fixed) - newClass = ByteUtility.addBytes(newClass,(short)20); // handler_pc (fixed) - } - newClass = ByteUtility.addBytes(newClass,(short)excpIndex[i][j]); // catch_type (variable) - } - // catch "exception" and trap it - newClass = ByteUtility.addBytes(newClass,(short)0); // start_pc (fixed) - if(propertyChangeFlag[i]) - { - newClass = ByteUtility.addBytes(newClass,(short)21); // end_pc (fixed) - newClass = ByteUtility.addBytes(newClass,(short)25); // handler_pc (fixed) - } - else - { - newClass = ByteUtility.addBytes(newClass,(short)19); // end_pc (fixed) - newClass = ByteUtility.addBytes(newClass,(short)23); // handler_pc (fixed) - } - if(nonExceptionable) - { newClass = ByteUtility.addBytes(newClass,(short)26); } // catch_type (fixed) - else // or - { newClass = ByteUtility.addBytes(newClass,(short)23); } // catch_type (fixed) - } - else - { newClass = ByteUtility.addBytes(newClass,(short)0); } // exception_table_length (fixed) - // attributes on the code attribute (none) - newClass = ByteUtility.addBytes(newClass,(short)0); // attribute_count (fixed) - // end code attribute - - - }/* End for*/ - // Class Attributes (none for this) - newClass = ByteUtility.addBytes(newClass,(short)0); // attribute_count (fixed) - /* done */ - - logger.debug("adapterName: " + finalAdapterClassName); - logger.debug("cpCount: " + count + " = " + BASECPCOUNT + " + " + cpCount); - logger.debug("methodCount: " + (lms.length+1)); - // output to disk class file - /* ****************************************************************************************** */ - - // now create the class and load it - // return the Class. - - if (writeClassFile) - { - try - { - // removed "WRITEDIRECTORY+", as this path is already part of 'finalAdapterClassName' - FileOutputStream fos = new FileOutputStream(finalAdapterClassName+".class"); - fos.write(newClass); - fos.close(); - } - catch(IOException ex) - { - System.err.println(ex.getMessage()); - ex.printStackTrace(); - } - - try - { - Class ret = ldr.loadClass(finalAdapterClassName); - logger.debug("EventAdapterGenerator: " + - ret.getName() + - " dynamically generated"); - return ret; - } - catch (ClassNotFoundException ex) - { - System.err.println(ex.getMessage()); - ex.printStackTrace(); - } - } - - try - { - Class ret = ldr.defineClass(finalAdapterClassName,newClass); - logger.debug("EventAdapterGenerator: " + - ret.getName() + - " dynamically generated"); - return ret; - } - catch(Exception ex) - { - System.err.println(ex.getMessage()); - ex.printStackTrace(); - } - } - return null; - } -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertor.java b/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertor.java deleted file mode 100644 index 9ded872a1..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertor.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.type; - -/** - * A TypeConvertor is used to convert an object of one type to - * one of another type. The convertor is invoked with the class of the - * from object, the desired class, and the from object itself. The - * convertor must return a new object of the desired class. - * - * @author Sanjiva Weerawarana - * @see TypeConvertorRegistry - */ -public interface TypeConvertor { - public Object convert (Class from, Class to, Object obj); - public String getCodeGenString (); -} diff --git a/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertorRegistry.java b/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertorRegistry.java deleted file mode 100644 index 693e464ee..000000000 --- a/src/main/java/com/volmit/iris/util/bsf/util/type/TypeConvertorRegistry.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2004,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.volmit.iris.util.bsf.util.type; - -import java.awt.Color; -import java.awt.Font; -import java.util.Hashtable; - -/** - * The TypeConvertorRegistry is the registry of type convertors. - * It has lookup and register capabilities based on the types to be - * converted as well as by some object key. - * - * @author Sanjiva Weerawarana - * @author Matthew J. Duftler - * @see TypeConvertorRegistry - */ -public class TypeConvertorRegistry { - Hashtable reg = new Hashtable (); - Hashtable keyedReg = new Hashtable (); - - // register some standard convertors at construction time - public TypeConvertorRegistry () { - // no-op convertors: cvt from primitive wrappers to the object wrapper - TypeConvertor tc = new TypeConvertor () { - public Object convert (Class from, Class to, Object obj) { - return obj; - } - - public String getCodeGenString() { - return "(Class from, Class to, Object obj) {\n" + - "return obj;\n" + - "}"; - } - }; - register (Boolean.class, boolean.class, tc); - register (boolean.class, Boolean.class, tc); - register (Byte.class, byte.class, tc); - register (byte.class, Byte.class, tc); - register (Character.class, char.class, tc); - register (char.class, Character.class, tc); - register (Short.class, short.class, tc); - register (short.class, Short.class, tc); - register (Integer.class, int.class, tc); - register (int.class, Integer.class, tc); - register (Long.class, long.class, tc); - register (long.class, Long.class, tc); - register (Float.class, float.class, tc); - register (float.class, Float.class, tc); - register (Double.class, double.class, tc); - register (double.class, Double.class, tc); - - // object to string: the registry special cases this one as the backup - // if the target is string and there is no special convertor available - // otherwise - tc = new TypeConvertor () { - public Object convert (Class from, Class to, Object obj) { - return (obj == null) ? "(null)" : obj.toString (); - } - - public String getCodeGenString() { - return "(Class from, Class to, Object obj) {\n" + - "return (obj == null) ? \"(null)\" : obj.toString ();\n" + - "}"; - } - }; - register (Object.class, String.class, tc); - - // convert strings to various primitives (both their object versions - // and wrappers for primitive versions) - tc = new TypeConvertor () { - public Object convert (Class from, Class to, Object obj) { - String str = (String) obj; - if (to == Boolean.class || to == boolean.class) { - return Boolean.valueOf (str); - } else if (to == Byte.class || to == byte.class) { - return Byte.valueOf (str); - } else if (to == Character.class || to == char.class) { - return new Character (str.charAt (0)); - } else if (to == Short.class || to == short.class) { - return Short.valueOf (str); - } else if (to == Integer.class || to == int.class) { - return Integer.valueOf (str); - } else if (to == Long.class || to == long.class) { - return Long.valueOf (str); - } else if (to == Float.class || to == float.class) { - return Float.valueOf (str); - } else if (to == Double.class || to == double.class) { - return Double.valueOf (str); - } else { - return null; - } - } - - public String getCodeGenString() { - return "(Class from, Class to, Object obj) {\n" + - "String str = (String) obj;\n" + - "if (to == Boolean.class || to == boolean.class) {\n" + - "return Boolean.valueOf (str);\n" + - "} else if (to == Byte.class || to == byte.class) {\n" + - "return Byte.valueOf (str);\n" + - "} else if (to == Character.class || to == char.class) {\n" + - "return new Character (str.charAt (0));\n" + - "} else if (to == Short.class || to == short.class) {\n" + - "return Short.valueOf (str);\n" + - "} else if (to == Integer.class || to == int.class) {\n" + - "return Integer.valueOf (str);\n" + - "} else if (to == Long.class || to == long.class) {\n" + - "return Long.valueOf (str);\n" + - "} else if (to == Float.class || to == float.class) {\n" + - "return Float.valueOf (str);\n" + - "} else if (to == Double.class || to == double.class) {\n" + - "return Double.valueOf (str);\n" + - "} else {\n" + - "return null;\n" + - "}\n" + - "}"; - } - }; - register (String.class, boolean.class, tc); - register (String.class, Boolean.class, tc); - register (String.class, byte.class, tc); - register (String.class, Byte.class, tc); - register (String.class, char.class, tc); - register (String.class, Character.class, tc); - register (String.class, short.class, tc); - register (String.class, Short.class, tc); - register (String.class, int.class, tc); - register (String.class, Integer.class, tc); - register (String.class, long.class, tc); - register (String.class, Long.class, tc); - register (String.class, float.class, tc); - register (String.class, Float.class, tc); - register (String.class, double.class, tc); - register (String.class, Double.class, tc); - - // strings to fonts - tc = new TypeConvertor () { - public Object convert (Class from, Class to, Object obj) { - return Font.decode ((String) obj); - } - - public String getCodeGenString() { - return "(Class from, Class to, Object obj) {\n" + - "return Font.decode ((String) obj);\n" + - "}"; - } - }; - register (String.class, Font.class, tc); - - // strings to colors - tc = new TypeConvertor () { - public Object convert (Class from, Class to, Object obj) { - return Color.decode ((String) obj); - } - - public String getCodeGenString() { - return "(Class from, Class to, Object obj) {\n" + - "return Color.decode ((String) obj);\n" + - "}"; - } - }; - register (String.class, Color.class, tc); - } - // lookup a convertor - public TypeConvertor lookup (Class from, Class to) { - String key = from.getName () + " -> " + to.getName (); - TypeConvertor tc = (TypeConvertor) reg.get (key); - if (tc == null) { - if (from != void.class - && from != Void.class - && to == String.class) { - // find the object -> string convertor - return lookup (Object.class, String.class); - } - } - return tc; - } - // lookup a convertor by key - public TypeConvertor lookupByKey (Object key) { - return (TypeConvertor) keyedReg.get (key); - } - // register a convertor - public void register (Class from, Class to, TypeConvertor convertor) { - String key = from.getName () + " -> " + to.getName (); - reg.put (key, convertor); - } - // register a convertor by key - public void registerByKey (Object key, TypeConvertor convertor) { - keyedReg.put (key, convertor); - } -} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 03f999133..59767aa97 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -12,6 +12,8 @@ libraries: - com.google.code.gson:gson:2.8.7 - it.unimi.dsi:fastutil:8.5.4 - com.google.guava:guava:30.1.1-jre + - bsf:bsf:2.4.0 + - rhino:js:1.7R2 commands: iris: aliases: [ ir, irs ] From afd482071348f7d8c5c5e163ad6263a1071c84fd Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sat, 7 Aug 2021 23:41:21 -0400 Subject: [PATCH 20/28] Fixes for scripts --- .../iris/core/project/SchemaBuilder.java | 21 ++++++++ .../iris/core/project/loader/IrisData.java | 51 +++++++++++++++++++ .../core/project/loader/ResourceLoader.java | 3 +- .../project/loader/ScriptResourceLoader.java | 6 +-- .../com/volmit/iris/engine/IrisEngine.java | 2 +- .../iris/engine/IrisExecutionEnvironment.java | 21 ++------ .../scripting/EngineExecutionEnvironment.java | 6 +-- .../engine/scripting/IrisScriptingAPI.java | 2 + 8 files changed, 87 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java index 27820352f..45588fcec 100644 --- a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java +++ b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java @@ -20,6 +20,7 @@ package com.volmit.iris.core.project; import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.project.loader.IrisRegistrant; import com.volmit.iris.core.project.loader.ResourceLoader; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; @@ -91,6 +92,26 @@ public class SchemaBuilder { o.put("type", getType(c)); JSONArray required = new JSONArray(); + if(c.isAssignableFrom(IrisRegistrant.class) || IrisRegistrant.class.isAssignableFrom(c)) + { + for (Field k : IrisRegistrant.class.getDeclaredFields()) { + k.setAccessible(true); + + if (Modifier.isStatic(k.getModifiers()) || Modifier.isFinal(k.getModifiers()) || Modifier.isTransient(k.getModifiers())) { + continue; + } + + JSONObject property = buildProperty(k, c); + + if (property.getBoolean("!required")) { + required.put(k.getName()); + } + + property.remove("!required"); + properties.put(k.getName(), property); + } + } + for (Field k : c.getDeclaredFields()) { k.setAccessible(true); diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java index 503571c37..4b6f19eb5 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java +++ b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java @@ -36,6 +36,9 @@ import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.engine.object.spawners.IrisSpawner; import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.context.IrisContext; +import com.volmit.iris.util.format.C; +import com.volmit.iris.util.format.Form; import com.volmit.iris.util.math.RNG; import lombok.Data; @@ -78,6 +81,54 @@ public class IrisData { hotloaded(); } + public void preprocessObject(IrisRegistrant t) + { + try + { + IrisContext ctx = IrisContext.get(); + Engine engine = this.engine; + + if(engine == null && ctx != null && ctx.getEngine() != null) + { + engine = ctx.getEngine(); + } + + if(engine == null && t.getPreprocessors().isNotEmpty()) + { + Iris.error("Failed to preprocess object " + t.getLoadKey() + " because there is no engine context here. (See stack below)"); + try + { + throw new RuntimeException(); + } + + catch(Throwable ex) + { + ex.printStackTrace(); + } + } + + if(engine != null && t.getPreprocessors().isNotEmpty()) + { + synchronized (this) + { + engine.getExecution().getAPI().setPreprocessorObject(t); + + for(String i : t.getPreprocessors()) + { + engine.getExecution().execute(i); + Iris.debug("Loader<" + C.GREEN + t.getTypeName() + C.LIGHT_PURPLE + "> iprocess " + C.YELLOW + t.getLoadKey() + C.LIGHT_PURPLE + " in " + i); + } + } + } + } + + catch(Throwable e) + { + Iris.error("Failed to preprocess object!"); + e.printStackTrace(); + } + } + public void close() { closed = true; dump(); diff --git a/src/main/java/com/volmit/iris/core/project/loader/ResourceLoader.java b/src/main/java/com/volmit/iris/core/project/loader/ResourceLoader.java index 5232fa9e6..a3ed3dbf9 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/ResourceLoader.java +++ b/src/main/java/com/volmit/iris/core/project/loader/ResourceLoader.java @@ -178,10 +178,11 @@ public class ResourceLoader { try { PrecisionStopwatch p = PrecisionStopwatch.start(); T t = new Gson().fromJson(IO.readAll(j), objectClass); - loadCache.put(key, t); t.setLoadKey(name); t.setLoadFile(j); t.setLoader(manager); + getManager().preprocessObject(t); + loadCache.put(key, t); logLoad(j, t); lock.unlock(); tlt.addAndGet(p.getMilliseconds()); diff --git a/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java b/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java index 50d7bdd6b..f3b31a799 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java +++ b/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java @@ -81,15 +81,15 @@ public class ScriptResourceLoader extends ResourceLoader { for (File i : getFolders()) { for (File j : i.listFiles()) { if (j.isFile() && j.getName().endsWith(".js")) { - m.add(j.getName().replaceAll("\\Q.iob\\E", "")); + m.add(j.getName().replaceAll("\\Q.js\\E", "")); } else if (j.isDirectory()) { for (File k : j.listFiles()) { if (k.isFile() && k.getName().endsWith(".js")) { - m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.iob\\E", "")); + m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.js\\E", "")); } else if (k.isDirectory()) { for (File l : k.listFiles()) { if (l.isFile() && l.getName().endsWith(".js")) { - m.add(j.getName() + "/" + k.getName() + "/" + l.getName().replaceAll("\\Q.iob\\E", "")); + m.add(j.getName() + "/" + k.getName() + "/" + l.getName().replaceAll("\\Q.js\\E", "")); } } } diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index c488a5a3c..d6d2f7176 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -101,6 +101,7 @@ public class IrisEngine extends BlockPopulator implements Engine { private final AtomicCache engineData = new AtomicCache<>(); public IrisEngine(EngineTarget target, EngineCompound compound, int index) { + execution = new IrisExecutionEnvironment(this); Iris.info("Initializing Engine: " + target.getWorld().name() + "/" + target.getDimension().getLoadKey() + " (" + target.getHeight() + " height)"); metrics = new EngineMetrics(32); this.target = target; @@ -120,7 +121,6 @@ public class IrisEngine extends BlockPopulator implements Engine { Iris.callEvent(new IrisEngineHotloadEvent(this)); context = new IrisContext(this); context.touch(); - execution = new IrisExecutionEnvironment(this); } @Override diff --git a/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java index 063eb5904..38eaae704 100644 --- a/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java +++ b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java @@ -49,6 +49,11 @@ public class IrisExecutionEnvironment implements EngineExecutionEnvironment { } } + @Override + public IrisScriptingAPI getAPI() { + return api; + } + public void execute(String script) { try { @@ -68,20 +73,4 @@ public class IrisExecutionEnvironment implements EngineExecutionEnvironment { return null; } - - @Override - public void execute(String script, double x, double y, double z) { - api.setX(x); - api.setY(y); - api.setZ(z); - execute(script); - } - - @Override - public Object evaluate(String script, double x, double y, double z) { - api.setX(x); - api.setY(y); - api.setZ(z); - return evaluate(script); - } } diff --git a/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java b/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java index a2ebd613a..43b476868 100644 --- a/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java +++ b/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java @@ -25,16 +25,14 @@ public interface EngineExecutionEnvironment { Engine getEngine(); + IrisScriptingAPI getAPI(); + BSFManager getManager(); void execute(String script); Object evaluate(String script); - void execute(String script, double x, double y, double z); - - Object evaluate(String script, double x, double y, double z); - default void close() { diff --git a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java index 835923c26..3c3f90e81 100644 --- a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java +++ b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java @@ -20,6 +20,7 @@ package com.volmit.iris.engine.scripting; import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.project.loader.IrisRegistrant; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineFramework; @@ -31,6 +32,7 @@ import lombok.Data; @Data public class IrisScriptingAPI { private final Engine engine; + private IrisRegistrant preprocessorObject; private double x = 0; private double y = 0; private double z = 0; From b74e449efd12e7dc5c3ea4b1e806f466e04750fd Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sat, 7 Aug 2021 23:41:26 -0400 Subject: [PATCH 21/28] Object preprocessors --- .../iris/core/project/loader/IrisRegistrant.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java b/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java index fa7a3a775..602146f25 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java +++ b/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java @@ -19,6 +19,12 @@ package com.volmit.iris.core.project.loader; import com.volmit.iris.Iris; +import com.volmit.iris.engine.object.annotations.ArrayType; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.RegistryListResource; +import com.volmit.iris.engine.object.common.IrisScript; +import com.volmit.iris.engine.object.dimensional.IrisDimensionIndex; +import com.volmit.iris.util.collection.KList; import lombok.Data; import java.awt.*; @@ -26,6 +32,11 @@ import java.io.File; @Data public abstract class IrisRegistrant { + @Desc("Preprocess this object in-memory when it's loaded, run scripts using the variable 'Iris.getPreprocessorObject()' and modify properties about this object before it's used.") + @RegistryListResource(IrisScript.class) + @ArrayType(min = 1, type = String.class) + private KList preprocessors = new KList<>(); + private transient IrisData loader; private transient String loadKey; From 33ea66ea883b81c7fb3f2a7d092c6e27f69634b1 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sun, 8 Aug 2021 00:22:25 -0400 Subject: [PATCH 22/28] Infinite energy option --- src/main/java/com/volmit/iris/engine/IrisWorldManager.java | 7 +++++++ .../iris/engine/object/dimensional/IrisDimension.java | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index 04e9cf732..a0ee4debf 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -87,8 +87,15 @@ public class IrisWorldManager extends EngineAssignedWorldManager { looper = new Looper() { @Override protected long loop() { + if(getDimension().isInfiniteEnergy()) + { + energy += 1000; + fixEnergy(); + } + if (M.ms() < charge) { energy += 70; + fixEnergy(); } if (cln.flip()) { diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java index 7e632b308..a908c4dd4 100644 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java @@ -316,6 +316,9 @@ public class IrisDimension extends IrisRegistrant { @Desc("Define carve layers") private KList carveLayers = new KList<>(); + @Desc("If true, the spawner system has infinite energy. This is NOT recommended because it would allow for mobs to keep spawning over and over without a rate limit") + private boolean infiniteEnergy = false; + @MinNumber(0.0001) @MaxNumber(512) @Desc("The rock zoom mostly for zooming in on a wispy palette") From 2d4301402945836f4202b5830e547f09e4f9d869 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sun, 8 Aug 2021 00:22:31 -0400 Subject: [PATCH 23/28] Scripted spawners --- .../iris/engine/IrisExecutionEnvironment.java | 3 + .../iris/engine/object/entity/IrisEntity.java | 58 +++++++++++++++++-- .../engine/scripting/IrisScriptingAPI.java | 4 ++ 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java index 38eaae704..629feb080 100644 --- a/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java +++ b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java @@ -22,6 +22,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.scripting.EngineExecutionEnvironment; import com.volmit.iris.engine.scripting.IrisScriptingAPI; +import com.volmit.iris.util.format.C; import lombok.Data; import org.apache.bsf.BSFEngine; import org.apache.bsf.BSFException; @@ -56,6 +57,7 @@ public class IrisExecutionEnvironment implements EngineExecutionEnvironment { public void execute(String script) { + Iris.debug("Execute Script (void) " + C.DARK_GREEN + script); try { javaScriptEngine.exec("", 0, 0, getEngine().getData().getScriptLoader().load(script)); } catch (BSFException e) { @@ -65,6 +67,7 @@ public class IrisExecutionEnvironment implements EngineExecutionEnvironment { public Object evaluate(String script) { + Iris.debug("Execute Script (for result) " + C.DARK_GREEN + script); try { return javaScriptEngine.eval("", 0, 0, getEngine().getData().getScriptLoader().load(script)); } catch (BSFException e) { diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java index 6c34aeb91..f2f436248 100644 --- a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java @@ -21,10 +21,8 @@ package com.volmit.iris.engine.object.entity; import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisRegistrant; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.object.annotations.ArrayType; -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.engine.object.annotations.RegistryListSpecialEntity; -import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.object.annotations.*; +import com.volmit.iris.engine.object.common.IrisScript; import com.volmit.iris.engine.object.loot.IrisLoot; import com.volmit.iris.engine.object.loot.IrisLootReference; import com.volmit.iris.engine.object.loot.IrisLootTable; @@ -155,17 +153,46 @@ public class IrisEntity extends IrisRegistrant { @Desc("Create a mob from another plugin, such as Mythic Mobs. Should be in the format of a namespace of PluginName:MobName") private String specialType = ""; + @Desc("Set the entity type to UNKNOWN, then define a script here which ends with the entity variable (the result). You can use Iris.getLocation() to find the target location. You can spawn any entity this way.") + @RegistryListResource(IrisScript.class) + private String spawnerScript = ""; + + @ArrayType(min = 1, type = String.class) + @Desc("Set the entity type to UNKNOWN, then define a script here. You can use Iris.getLocation() to find the target location. You can spawn any entity this way.") + @RegistryListResource(IrisScript.class) + private KList postSpawnScripts = new KList<>(); + public Entity spawn(Engine gen, Location at) { return spawn(gen, at, new RNG(at.hashCode())); } public Entity spawn(Engine gen, Location at, RNG rng) { - Entity e = doSpawn(at); + Entity ee = doSpawn(at); - if (e == null) { + if(!spawnerScript.isEmpty() && ee == null) + { + synchronized (this) + { + gen.getExecution().getAPI().setLocation(at); + try + { + ee = (Entity) gen.getExecution().evaluate(spawnerScript); + } + + catch(Throwable ex) + { + Iris.error("You must return an Entity in your scripts to use entity scripts!"); + ex.printStackTrace(); + } + } + } + + if(ee == null) + { return null; } + Entity e = ee; e.setCustomName(getCustomName() != null ? C.translateAlternateColorCodes('&', getCustomName()) : null); e.setCustomNameVisible(isCustomNameVisible()); e.setGlowing(isGlowing()); @@ -286,10 +313,29 @@ public class IrisEntity extends IrisRegistrant { spawnEffect.apply(e); } + if(postSpawnScripts.isNotEmpty()) + { + synchronized (this) + { + gen.getExecution().getAPI().setLocation(at); + gen.getExecution().getAPI().setEntity(ee); + + for(String i : postSpawnScripts) + { + gen.getExecution().execute(i); + } + } + } + return e; } private Entity doSpawn(Location at) { + if(type.equals(EntityType.UNKNOWN)) + { + return null; + } + if (!Bukkit.isPrimaryThread()) { // Someone called spawn (worldedit maybe?) on a non server thread // Due to the structure of iris, we will call it sync and busy wait until it's done. diff --git a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java index 3c3f90e81..a6671c0e8 100644 --- a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java +++ b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java @@ -28,6 +28,8 @@ import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.object.noise.IrisExpression; import lombok.Data; +import org.bukkit.Location; +import org.bukkit.entity.Entity; @Data public class IrisScriptingAPI { @@ -36,6 +38,8 @@ public class IrisScriptingAPI { private double x = 0; private double y = 0; private double z = 0; + private Location location; + private Entity entity; public IrisScriptingAPI(Engine engine) { From 7f6fec5530085c35f12072742e60375e4d961f20 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sun, 8 Aug 2021 01:12:16 -0400 Subject: [PATCH 24/28] Fixes --- .../volmit/iris/engine/IrisWorldManager.java | 20 ++++++++++++++++++- .../iris/engine/object/noise/NoiseStyle.java | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index a0ee4debf..6258067af 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -87,6 +87,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager { looper = new Looper() { @Override protected long loop() { + if(getEngine().isClosed()) + { + interrupt(); + } + if(getDimension().isInfiniteEnergy()) { energy += 1000; @@ -133,6 +138,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } private boolean onAsyncTick() { + if(getEngine().isClosed()) + { + return false; + } + actuallySpawned = 0; if (energy < 100) { @@ -154,7 +164,15 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } if (cl.flip()) { - J.s(() -> precount = getEngine().getWorld().realWorld().getEntities()); + try + { + J.s(() -> precount = getEngine().getWorld().realWorld().getEntities()); + } + + catch(Throwable e) + { + close(); + } } int chunkCooldownSeconds = 60; diff --git a/src/main/java/com/volmit/iris/engine/object/noise/NoiseStyle.java b/src/main/java/com/volmit/iris/engine/object/noise/NoiseStyle.java index 7eebe66c6..5d6412fdc 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/NoiseStyle.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/NoiseStyle.java @@ -45,7 +45,7 @@ public enum NoiseStyle { @Desc("Clover Noise") CLOVER(rng -> new CNG(rng, NoiseType.CLOVER, 1D, 1).scale(0.06).bake()), - + @Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.") CLOVER_STARCAST_3(rng -> new CNG(rng, NoiseType.CLOVER_STARCAST_3, 1D, 1)), From 4e131d9a54377481112fba3934ee3bf3c3c165f5 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sun, 8 Aug 2021 01:13:53 -0400 Subject: [PATCH 25/28] Fix async spawn issue on spigot --- .../java/com/volmit/iris/engine/IrisWorldManager.java | 10 +++++++++- .../volmit/iris/engine/object/noise/NoiseStyle.java | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index 6258067af..b44d5573f 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -241,7 +241,15 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } } - spawn(c, v); + try + { + spawn(c, v); + } + + catch(Throwable e) + { + J.s(() -> spawn(c, v)); + } } //@done } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/NoiseStyle.java b/src/main/java/com/volmit/iris/engine/object/noise/NoiseStyle.java index 5d6412fdc..7eebe66c6 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/NoiseStyle.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/NoiseStyle.java @@ -45,7 +45,7 @@ public enum NoiseStyle { @Desc("Clover Noise") CLOVER(rng -> new CNG(rng, NoiseType.CLOVER, 1D, 1).scale(0.06).bake()), - + @Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.") CLOVER_STARCAST_3(rng -> new CNG(rng, NoiseType.CLOVER_STARCAST_3, 1D, 1)), From 1781ff36c6264b7b32172e024f14cd6d5d97b9de Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sun, 8 Aug 2021 01:57:46 -0400 Subject: [PATCH 26/28] V+ --- build.gradle | 2 +- .../java/com/volmit/iris/engine/IrisEngineFramework.java | 1 + src/main/java/com/volmit/iris/util/io/ReactiveFolder.java | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 69a910474..528db0f56 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ plugins { } group 'com.volmit.iris' -version '1.6.5' +version '1.6.6' def apiVersion = '1.17' def name = 'Iris' def main = 'com.volmit.iris.Iris' diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java b/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java index b50843661..44fdc7fde 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java @@ -29,6 +29,7 @@ import com.volmit.iris.engine.modifier.IrisCaveModifier; import com.volmit.iris.engine.modifier.IrisDepositModifier; import com.volmit.iris.engine.modifier.IrisPostModifier; import com.volmit.iris.engine.modifier.IrisRavineModifier; +import com.volmit.iris.util.io.ReactiveFolder; import com.volmit.iris.util.scheduling.ChronoLatch; import lombok.Getter; import org.bukkit.block.Biome; diff --git a/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java b/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java index 8dc1fe0b6..8d12b7fd8 100644 --- a/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java +++ b/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java @@ -46,7 +46,7 @@ public class ReactiveFolder { if (checkCycle % 3 == 0 ? fw.checkModified() : fw.checkModifiedFast()) { for (File i : fw.getCreated()) { - if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")) { + if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")|| i.getName().endsWith(".js")) { modified = true; break; } @@ -54,7 +54,7 @@ public class ReactiveFolder { if (!modified) { for (File i : fw.getChanged()) { - if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")) { + if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")|| i.getName().endsWith(".js")) { modified = true; break; } @@ -63,7 +63,7 @@ public class ReactiveFolder { if (!modified) { for (File i : fw.getDeleted()) { - if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")) { + if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")|| i.getName().endsWith(".js")) { modified = true; break; } From 366c903f843136c51f9ecec262049ceea3f843d0 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sun, 8 Aug 2021 03:44:25 -0400 Subject: [PATCH 27/28] Mantle fixes --- .../iris/engine/mantle/EngineMantle.java | 1 - .../iris/engine/mantle/MantleSized.java | 23 ++++++++ .../volmit/iris/util/mantle/MantleChunk.java | 39 +++++++++++- .../iris/util/matter/slices/ZoneMatter.java | 59 +++++++++++++++++++ 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/volmit/iris/engine/mantle/MantleSized.java create mode 100644 src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index 97e55341c..f1277e18c 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -22,7 +22,6 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineComponent; import com.volmit.iris.engine.framework.EngineFramework; import com.volmit.iris.engine.framework.EngineTarget; import com.volmit.iris.engine.object.common.IObjectPlacer; diff --git a/src/main/java/com/volmit/iris/engine/mantle/MantleSized.java b/src/main/java/com/volmit/iris/engine/mantle/MantleSized.java new file mode 100644 index 000000000..1668a182d --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/mantle/MantleSized.java @@ -0,0 +1,23 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.mantle; + +public interface MantleSized { + public int getMaxChunkSize(); +} diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java index 136c3b27e..574c4a650 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java @@ -18,6 +18,9 @@ package com.volmit.iris.util.mantle; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.data.Varint; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.matter.IrisMatter; @@ -33,6 +36,7 @@ import java.util.concurrent.atomic.AtomicReferenceArray; * Mantle Chunks are fully atomic & thread safe */ public class MantleChunk { + private final KSet flags; private final AtomicReferenceArray sections; /** @@ -43,6 +47,7 @@ public class MantleChunk { @ChunkCoordinates public MantleChunk(int sectionHeight) { sections = new AtomicReferenceArray<>(sectionHeight); + flags = new KSet<>(); } /** @@ -55,7 +60,13 @@ public class MantleChunk { */ public MantleChunk(int sectionHeight, DataInputStream din) throws IOException, ClassNotFoundException { this(sectionHeight); - int s = Varint.readUnsignedVarInt(din); + int s = din.readByte(); + int f = din.readByte(); + + for(int i = 0; i < f; i++) + { + flags.add(din.readUTF()); + } for (int i = 0; i < s; i++) { if (din.readBoolean()) { @@ -64,6 +75,24 @@ public class MantleChunk { } } + public void flag(String s, boolean f) + { + if(f) + { + flags.add(s); + } + + else + { + flags.remove(s); + } + } + + public boolean isFlagged(String s) + { + return flags.contains(s); + } + /** * Check if a section exists (same as get(section) != null) * @@ -130,7 +159,13 @@ public class MantleChunk { * @throws IOException shit happens */ public void write(DataOutputStream dos) throws IOException { - Varint.writeUnsignedVarInt(sections.length(), dos); + dos.writeByte(sections.length()); + dos.writeByte(flags.size()); + + for(String i : flags) + { + dos.writeUTF(i); + } for (int i = 0; i < sections.length(); i++) { if (exists(i)) { diff --git a/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java new file mode 100644 index 000000000..35a914042 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java @@ -0,0 +1,59 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.matter.slices; + +import com.volmit.iris.engine.object.feature.IrisFeaturePositional; +import com.volmit.iris.util.matter.Sliced; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +@Sliced +public class ZoneMatter extends RawMatter { + public ZoneMatter() { + this(1, 1, 1); + } + + public ZoneMatter(int width, int height, int depth) { + super(width, height, depth, IrisFeaturePositional.class); + } + + @Override + public void setRaw(int x, int y, int z, IrisFeaturePositional t) { + for(int i = 0; i < getHeight(); i++) + { + if(get(x, i, z) == null) + { + super.setRaw(x, i, z, t); + break; + } + } + } + + @Override + public void writeNode(IrisFeaturePositional b, DataOutputStream dos) throws IOException { + b.write(dos); + } + + @Override + public IrisFeaturePositional readNode(DataInputStream din) throws IOException { + return IrisFeaturePositional.read(din); + } +} From f50ac49edead037b5d6515bf79ff61f82c0a9b80 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sun, 8 Aug 2021 04:53:14 -0400 Subject: [PATCH 28/28] The engine is the framework --- src/main/java/com/volmit/iris/Iris.java | 1 - .../volmit/iris/core/IrisBoardManager.java | 4 +- .../volmit/iris/core/command/CommandIris.java | 5 +- .../pregen/CommandIrisPregenPause.java | 2 +- .../pregen/CommandIrisPregenStart.java | 55 +++---- .../command/pregen/CommandIrisPregenStop.java | 8 +- .../studio/CommandIrisStudioExecute.java | 6 +- .../command/what/CommandIrisWhatFeatures.java | 2 +- .../core/command/world/CommandIrisFix.java | 4 +- .../com/volmit/iris/core/gui/VisionGUI.java | 20 +-- .../core/gui/components/IrisRenderer.java | 12 +- .../iris/core/link/IrisPapiExpansion.java | 2 +- .../iris/core/project/SchemaBuilder.java | 3 +- .../iris/core/project/loader/IrisData.java | 41 ++---- .../core/project/loader/IrisRegistrant.java | 1 - .../project/loader/ScriptResourceLoader.java | 8 - .../com/volmit/iris/engine/IrisComplex.java | 18 +-- .../com/volmit/iris/engine/IrisEngine.java | 132 +++++++++++------ .../iris/engine/IrisEngineFramework.java | 138 ------------------ .../volmit/iris/engine/IrisEngineMantle.java | 3 +- .../iris/engine/IrisExecutionEnvironment.java | 10 +- .../volmit/iris/engine/IrisWorldManager.java | 27 +--- .../volmit/iris/engine/framework/Engine.java | 49 +++++-- .../engine/framework/EngineComponent.java | 6 +- .../iris/engine/framework/EngineCompound.java | 2 +- .../engine/framework/EngineFramework.java | 58 -------- .../framework/EngineParallaxManager.java | 14 +- .../iris/engine/mantle/EngineMantle.java | 20 +-- .../iris/engine/mantle/MantleSized.java | 2 +- .../engine/modifier/IrisPostModifier.java | 12 +- .../iris/engine/object/common/IrisScript.java | 10 +- .../iris/engine/object/entity/IrisEntity.java | 29 ++-- .../engine/object/entity/IrisEntitySpawn.java | 6 +- .../object/noise/IrisEngineStreamType.java | 8 +- .../object/noise/IrisEngineValueType.java | 16 +- .../object/noise/IrisExpressionLoad.java | 8 +- .../scripting/EngineExecutionEnvironment.java | 6 +- .../engine/scripting/IrisScriptingAPI.java | 44 ++---- .../volmit/iris/util/context/IrisContext.java | 5 +- .../volmit/iris/util/io/ReactiveFolder.java | 6 +- .../volmit/iris/util/mantle/MantleChunk.java | 23 +-- .../iris/util/matter/slices/ZoneMatter.java | 6 +- 42 files changed, 289 insertions(+), 543 deletions(-) delete mode 100644 src/main/java/com/volmit/iris/engine/IrisEngineFramework.java delete mode 100644 src/main/java/com/volmit/iris/engine/framework/EngineFramework.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 51d28fe8e..863eebfcf 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -30,7 +30,6 @@ import com.volmit.iris.core.link.OraxenLink; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; -import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.EngineCompositeGenerator; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiomeCustom; diff --git a/src/main/java/com/volmit/iris/core/IrisBoardManager.java b/src/main/java/com/volmit/iris/core/IrisBoardManager.java index 7dca937e8..8116a4de5 100644 --- a/src/main/java/com/volmit/iris/core/IrisBoardManager.java +++ b/src/main/java/com/volmit/iris/core/IrisBoardManager.java @@ -148,12 +148,12 @@ public class IrisBoardManager implements BoardProvider, Listener { if (engine != null) { v.add("&7&m------------------"); KList f = new KList<>(); - f.add(engine.getFramework().getEngineParallax().forEachFeature(x, z)); + f.add(engine.getEngineParallax().forEachFeature(x, z)); v.add(C.AQUA + "Engine" + C.GRAY + ": " + engine.getName() + " " + engine.getMinHeight() + "-" + engine.getMaxHeight()); v.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName()); v.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiome(x, y, z).getName()); v.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z))); - v.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getFramework().getComplex().getSlopeStream().get(x, z), 2)); + v.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2)); v.add(C.AQUA + "Features" + C.GRAY + ": " + Form.f(f.size())); v.add(C.AQUA + "Energy" + C.GRAY + ": " + Form.f(engine.getWorldManager().getEnergy(), 0)); v.add(C.AQUA + "Sat" + C.GRAY + ": " + Form.f(engine.getWorldManager().getEntityCount()) + "e / " + Form.f(engine.getWorldManager().getChunkCount()) + "c (" + Form.pc(engine.getWorldManager().getEntitySaturation(), 0) + ")"); diff --git a/src/main/java/com/volmit/iris/core/command/CommandIris.java b/src/main/java/com/volmit/iris/core/command/CommandIris.java index a8f4250c8..d88d7fadc 100644 --- a/src/main/java/com/volmit/iris/core/command/CommandIris.java +++ b/src/main/java/com/volmit/iris/core/command/CommandIris.java @@ -24,7 +24,10 @@ import com.volmit.iris.core.command.object.CommandIrisObject; import com.volmit.iris.core.command.pregen.CommandIrisPregen; import com.volmit.iris.core.command.studio.CommandIrisStudio; import com.volmit.iris.core.command.what.CommandIrisWhat; -import com.volmit.iris.core.command.world.*; +import com.volmit.iris.core.command.world.CommandIrisCreate; +import com.volmit.iris.core.command.world.CommandIrisFix; +import com.volmit.iris.core.command.world.CommandIrisUpdateWorld; +import com.volmit.iris.core.command.world.CommandIrisVerify; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.Command; import com.volmit.iris.util.plugin.MortarCommand; diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenPause.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenPause.java index 66d324d3d..6dac3c1a5 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenPause.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenPause.java @@ -17,7 +17,7 @@ public class CommandIrisPregenPause extends MortarCommand { @Override public boolean handle(VolmitSender sender, String[] args) { - if (PregeneratorJob.pauseResume()){ + if (PregeneratorJob.pauseResume()) { sender.sendMessage("Paused/unpaused pregeneration task, now: " + (PregeneratorJob.isPaused() ? "Paused" : "Running") + "."); } else { sender.sendMessage("No active pregeneration tasks to pause/unpause."); diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java index 1c0ea3342..10eff2735 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStart.java @@ -11,8 +11,6 @@ import com.volmit.iris.util.plugin.VolmitSender; import org.bukkit.Bukkit; import org.bukkit.World; -import java.util.Arrays; - public class CommandIrisPregenStart extends MortarCommand { @@ -26,12 +24,12 @@ public class CommandIrisPregenStart extends MortarCommand { Create a new pregeneration task. Command usage: /iris pregen create [radius=] [x=] [z=] [world=] [-here] - + Examples: /iris pregen start 5k -here /iris pregen start radius=5000 x=10r z=10r world=IrisWorld /iris pregen start 10k world=WorldName - + : Sets both width and height to a value. (Size is: 2 * radius by 2 * radius) & : Give the center point of the pregen. : Specify a different world name for generation than the one you're currently in. @@ -39,7 +37,7 @@ public class CommandIrisPregenStart extends MortarCommand { If you specify this, the `-here` is ignored. -here: If added, the center location is set to your position (player only) This overrides and . - + For all numeric values (radius, centerX, etc.) you may use: c => 16, r => 512, k => 1000 Example: entering '1000' is the same as '1k' (1 * 1000) @@ -53,7 +51,7 @@ public class CommandIrisPregenStart extends MortarCommand { argus.forEach(p -> { boolean hasArg = false; for (String arg : args) { - if (!arg.contains("=") || !p.contains("=")){ + if (!arg.contains("=") || !p.contains("=")) { continue; } if (arg.split("=")[0].equals(p.split("=")[0])) { @@ -61,7 +59,7 @@ public class CommandIrisPregenStart extends MortarCommand { break; } } - if (!hasArg){ + if (!hasArg) { list.add(p); } }); @@ -74,12 +72,12 @@ public class CommandIrisPregenStart extends MortarCommand { break; } } - if (!hasHere){ + if (!hasHere) { list.add("-here"); } // Add Iris worlds - if (Bukkit.getWorlds().isEmpty()){ + if (Bukkit.getWorlds().isEmpty()) { list.add("world="); } else { Bukkit.getWorlds().forEach(w -> { @@ -114,21 +112,21 @@ public class CommandIrisPregenStart extends MortarCommand { // Check all arguments KList failed = new KList<>(); for (String a : args) { - if (a.equals("-here")){ + if (a.equals("-here")) { here = true; } else if (a.contains("=")) { String pre = a.split("=")[0]; String val = a.split("=")[1]; - if (pre.equals("world")){ + if (pre.equals("world")) { world = Bukkit.getWorld(val); - if (world == null){ + if (world == null) { failed.add(a + " (invalid world)"); sender.sendMessage("Entered world is " + val + ", but that world does not exist."); sender.sendMessage("Cancelling the command."); sender.sendMessage(getDescription()); return true; } - } else if (!isVal(val)){ + } else if (!isVal(val)) { failed.add(a + " (non-value)"); } else { switch (pre) { @@ -152,15 +150,15 @@ public class CommandIrisPregenStart extends MortarCommand { } // Checking if a radius was specified or forgotten - if (width == -1 || height == -1){ + if (width == -1 || height == -1) { sender.sendMessage("Radius not specified! Cancelling..."); sender.sendMessage(getDescription()); return true; } // World specified & cancelling `-here` if it's another world - if (world == null){ - if (sender.isPlayer()){ + if (world == null) { + if (sender.isPlayer()) { world = sender.player().getWorld(); } else { sender.sendMessage("Must specify world= if sending from console! Cancelling..."); @@ -168,8 +166,8 @@ public class CommandIrisPregenStart extends MortarCommand { return true; } } else { - if (sender.isPlayer()){ - if (!world.equals(sender.player().getWorld())){ + if (sender.isPlayer()) { + if (!world.equals(sender.player().getWorld())) { if (here) { sender.sendMessage("Ignoring `-here` because `world=` is specified!"); here = false; @@ -179,7 +177,7 @@ public class CommandIrisPregenStart extends MortarCommand { } // Checking if -here is used - if (here){ + if (here) { if (sender.isPlayer()) { x = sender.player().getLocation().getBlockX(); z = sender.player().getLocation().getBlockZ(); @@ -207,14 +205,14 @@ public class CommandIrisPregenStart extends MortarCommand { .append(z) .append("\n") - // Append failed args + // Append failed args .append(failed.isEmpty() ? "(No failed arguments)\n" : "FAILED ARGS:\n"); for (String s : failed) { details.append(s).append("\n"); } // Start pregen and append info to details - if (pregenerate(world, width, height, x, z)){ + if (pregenerate(world, width, height, x, z)) { details.append("Successfully started pregen"); } else { details.append("Failed to start pregen. Doublecheck your arguments!"); @@ -228,14 +226,15 @@ public class CommandIrisPregenStart extends MortarCommand { /** * Pregenerate a - * @param world world with a - * @param width and + * + * @param world world with a + * @param width and * @param height with center - * @param x and - * @param z coords + * @param x and + * @param z coords * @return true if successful */ - private boolean pregenerate(World world, int width, int height, int x, int z){ + private boolean pregenerate(World world, int width, int height, int x, int z) { try { IrisToolbelt.pregenerate(PregenTask .builder() @@ -243,7 +242,7 @@ public class CommandIrisPregenStart extends MortarCommand { .width(width >> 9 + 1) .height(height >> 9 + 1) .build(), world); - } catch (Throwable e){ + } catch (Throwable e) { Iris.reportError(e); e.printStackTrace(); return false; @@ -254,6 +253,7 @@ public class CommandIrisPregenStart extends MortarCommand { /** * Get the ingeger value from an argument that may contain `c` `chunks` `r` `regions` or `k`
* "5r" returns 5 * 512 = 2560 + * * @param arg the string argument to parse into a value * @return the integer value result */ @@ -276,6 +276,7 @@ public class CommandIrisPregenStart extends MortarCommand { /** * Checks if the + * * @param arg string value * @return is valid -> true */ diff --git a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java index 17a864730..13312b0db 100644 --- a/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java +++ b/src/main/java/com/volmit/iris/core/command/pregen/CommandIrisPregenStop.java @@ -2,15 +2,9 @@ package com.volmit.iris.core.command.pregen; import com.volmit.iris.Iris; import com.volmit.iris.core.gui.PregeneratorJob; -import com.volmit.iris.core.pregenerator.PregenTask; -import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod; -import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; -import org.bukkit.Bukkit; -import org.bukkit.World; public class CommandIrisPregenStop extends MortarCommand { @@ -23,7 +17,7 @@ public class CommandIrisPregenStop extends MortarCommand { @Override public boolean handle(VolmitSender sender, String[] args) { - if (PregeneratorJob.shutdownInstance()){ + if (PregeneratorJob.shutdownInstance()) { sender.sendMessage("Stopped pregeneration task"); } else { sender.sendMessage("No active pregeneration tasks to stop"); diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java index a63017d48..269b0a498 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java @@ -25,7 +25,6 @@ import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.IrisAccess; -import com.volmit.iris.engine.object.common.IrisScript; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; @@ -61,9 +60,8 @@ public class CommandIrisStudioExecute extends MortarCommand { IrisAccess a = IrisToolbelt.access(sender.player().getWorld()); - if(a != null) - { - ((Engine)a.getEngineAccess(0)).getExecution().execute(args[0]); + if (a != null) { + ((Engine) a.getEngineAccess(0)).getExecution().execute(args[0]); Iris.info("Executed. See script output in console."); } diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java index 379a81241..b348d0f00 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java @@ -53,7 +53,7 @@ public class CommandIrisWhatFeatures extends MortarCommand { if (IrisWorlds.isIrisWorld(c.getWorld())) { int m = 1; - for (IrisFeaturePositional i : ((Engine) IrisWorlds.access(c.getWorld()).getEngineAccess(p.getLocation().getBlockY())).getFramework().getEngineParallax().getFeaturesInChunk(c)) { + for (IrisFeaturePositional i : ((Engine) IrisWorlds.access(c.getWorld()).getEngineAccess(p.getLocation().getBlockY())).getEngineParallax().getFeaturesInChunk(c)) { sender.sendMessage("#" + m++ + " " + new JSONObject(new Gson().toJson(i)).toString(4)); } } else { diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java index 8d91fa0a1..27f655d8d 100644 --- a/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java @@ -55,13 +55,13 @@ public class CommandIrisFix extends MortarCommand { int viewDistance = args.length > 0 ? Integer.parseInt(args[0]) : -1; if (viewDistance <= 1) { J.a(() -> { - int fixed = a.getCompound().getDefaultEngine().getFramework().getEngineParallax().repairChunk(sender.player().getLocation().getChunk()); + int fixed = a.getCompound().getDefaultEngine().getEngineParallax().repairChunk(sender.player().getLocation().getChunk()); sender.sendMessage("Fixed " + Form.f(fixed) + " blocks!"); }); } else { AtomicInteger v = new AtomicInteger(); J.a(() -> { - new Spiraler(viewDistance, viewDistance, (x, z) -> v.set(v.get() + a.getCompound().getDefaultEngine().getFramework().getEngineParallax().repairChunk(sender.player().getWorld().getChunkAt(x, z)))).drain(); + new Spiraler(viewDistance, viewDistance, (x, z) -> v.set(v.get() + a.getCompound().getDefaultEngine().getEngineParallax().repairChunk(sender.player().getWorld().getChunkAt(x, z)))).drain(); sender.sendMessage("Fixed " + Form.f(v.get()) + " blocks in " + (viewDistance * viewDistance) + " chunks!"); }); } diff --git a/src/main/java/com/volmit/iris/core/gui/VisionGUI.java b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java index db2dfb07e..4aefbb6bd 100644 --- a/src/main/java/com/volmit/iris/core/gui/VisionGUI.java +++ b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java @@ -191,12 +191,12 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener BiFunction colorFunction = (d, dx) -> Color.black.getRGB(); switch (currentType) { - case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> engine.getFramework().getComplex().getTrueBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); - case BIOME_LAND -> colorFunction = (x, z) -> engine.getFramework().getComplex().getLandBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); - case BIOME_SEA -> colorFunction = (x, z) -> engine.getFramework().getComplex().getSeaBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); - case REGION -> colorFunction = (x, z) -> engine.getFramework().getComplex().getRegionStream().get(x, z).getColor(engine.getFramework().getComplex(), currentType).getRGB(); - case CAVE_LAND -> colorFunction = (x, z) -> engine.getFramework().getComplex().getCaveBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); - case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(engine.getFramework().getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); + case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> engine.getComplex().getTrueBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); + case BIOME_LAND -> colorFunction = (x, z) -> engine.getComplex().getLandBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); + case BIOME_SEA -> colorFunction = (x, z) -> engine.getComplex().getSeaBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); + case REGION -> colorFunction = (x, z) -> engine.getComplex().getRegionStream().get(x, z).getColor(engine.getComplex(), currentType).getRGB(); + case CAVE_LAND -> colorFunction = (x, z) -> engine.getComplex().getCaveBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); + case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(engine.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); } return colorFunction.apply(wx, wz); @@ -629,8 +629,8 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener } private void renderHoverOverlay(Graphics2D g, boolean detailed) { - IrisBiome biome = engine.getFramework().getComplex().getTrueBiomeStream().get(getWorldX(hx), getWorldZ(hz)); - IrisRegion region = engine.getFramework().getComplex().getRegionStream().get(getWorldX(hx), getWorldZ(hz)); + IrisBiome biome = engine.getComplex().getTrueBiomeStream().get(getWorldX(hx), getWorldZ(hz)); + IrisRegion region = engine.getComplex().getRegionStream().get(getWorldX(hx), getWorldZ(hz)); KList l = new KList<>(); l.add("Biome: " + biome.getName()); l.add("Region: " + region.getName() + "(" + region.getLoadKey() + ")"); @@ -692,7 +692,7 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener } private void open() { - IrisComplex complex = engine.getFramework().getComplex(); + IrisComplex complex = engine.getComplex(); File r = null; switch (currentType) { case BIOME, LAYER_LOAD, DECORATOR_LOAD, OBJECT_LOAD, HEIGHT -> r = complex.getTrueBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); @@ -710,7 +710,7 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener if (player != null) { int xx = (int) getWorldX(hx); int zz = (int) getWorldZ(hz); - double h = engine.getFramework().getComplex().getTrueHeightStream().get(xx, zz); + double h = engine.getComplex().getTrueHeightStream().get(xx, zz); player.teleport(new Location(player.getWorld(), xx, h, zz)); notify("Teleporting to " + xx + ", " + (int) h + ", " + zz); } else { diff --git a/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java b/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java index bd6e5d1c0..944b4af3a 100644 --- a/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java +++ b/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java @@ -38,12 +38,12 @@ public class IrisRenderer { BiFunction colorFunction = (d, dx) -> Color.black.getRGB(); switch (currentType) { - case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getTrueBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); - case BIOME_LAND -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getLandBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); - case BIOME_SEA -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getSeaBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); - case REGION -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getRegionStream().get(x, z).getColor(renderer.getFramework().getComplex(), currentType).getRGB(); - case CAVE_LAND -> colorFunction = (x, z) -> renderer.getFramework().getComplex().getCaveBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); - case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(renderer.getFramework().getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); + case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> renderer.getComplex().getTrueBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); + case BIOME_LAND -> colorFunction = (x, z) -> renderer.getComplex().getLandBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); + case BIOME_SEA -> colorFunction = (x, z) -> renderer.getComplex().getSeaBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); + case REGION -> colorFunction = (x, z) -> renderer.getComplex().getRegionStream().get(x, z).getColor(renderer.getComplex(), currentType).getRGB(); + case CAVE_LAND -> colorFunction = (x, z) -> renderer.getComplex().getCaveBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); + case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(renderer.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); } double x, z; diff --git a/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java b/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java index ea33c8100..cd1d70476 100644 --- a/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java +++ b/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java @@ -85,7 +85,7 @@ public class IrisPapiExpansion extends PlaceholderExpansion { } else if (p.equalsIgnoreCase("terrain_slope")) { if (a != null) { return ((Engine) a.getEngineAccess(l.getBlockY())) - .getFramework().getComplex().getSlopeStream() + .getComplex().getSlopeStream() .get(l.getX(), l.getZ()) + ""; } } else if (p.equalsIgnoreCase("terrain_height")) { diff --git a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java index 45588fcec..c77d29000 100644 --- a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java +++ b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java @@ -92,8 +92,7 @@ public class SchemaBuilder { o.put("type", getType(c)); JSONArray required = new JSONArray(); - if(c.isAssignableFrom(IrisRegistrant.class) || IrisRegistrant.class.isAssignableFrom(c)) - { + if (c.isAssignableFrom(IrisRegistrant.class) || IrisRegistrant.class.isAssignableFrom(c)) { for (Field k : IrisRegistrant.class.getDeclaredFields()) { k.setAccessible(true); diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java index 4b6f19eb5..e56fdc42d 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java +++ b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java @@ -38,7 +38,6 @@ import com.volmit.iris.engine.object.spawners.IrisSpawner; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; import com.volmit.iris.util.math.RNG; import lombok.Data; @@ -81,49 +80,35 @@ public class IrisData { hotloaded(); } - public void preprocessObject(IrisRegistrant t) - { - try - { + public void preprocessObject(IrisRegistrant t) { + try { IrisContext ctx = IrisContext.get(); Engine engine = this.engine; - if(engine == null && ctx != null && ctx.getEngine() != null) - { + if (engine == null && ctx != null && ctx.getEngine() != null) { engine = ctx.getEngine(); } - if(engine == null && t.getPreprocessors().isNotEmpty()) - { + if (engine == null && t.getPreprocessors().isNotEmpty()) { Iris.error("Failed to preprocess object " + t.getLoadKey() + " because there is no engine context here. (See stack below)"); - try - { + try { throw new RuntimeException(); - } - - catch(Throwable ex) - { + } catch (Throwable ex) { ex.printStackTrace(); } } - if(engine != null && t.getPreprocessors().isNotEmpty()) - { - synchronized (this) - { + if (engine != null && t.getPreprocessors().isNotEmpty()) { + synchronized (this) { engine.getExecution().getAPI().setPreprocessorObject(t); - for(String i : t.getPreprocessors()) - { + for (String i : t.getPreprocessors()) { engine.getExecution().execute(i); Iris.debug("Loader<" + C.GREEN + t.getTypeName() + C.LIGHT_PURPLE + "> iprocess " + C.YELLOW + t.getLoadKey() + C.LIGHT_PURPLE + " in " + i); } } } - } - - catch(Throwable e) - { + } catch (Throwable e) { Iris.error("Failed to preprocess object!"); e.printStackTrace(); } @@ -149,11 +134,9 @@ public class IrisData { ResourceLoader r = null; if (registrant.equals(IrisObject.class)) { r = (ResourceLoader) new ObjectResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName()); - } - else if (registrant.equals(IrisScript.class)) { + } else if (registrant.equals(IrisScript.class)) { r = (ResourceLoader) new ScriptResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName()); - } - else { + } else { r = new ResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName(), registrant); } diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java b/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java index 602146f25..c457f19b4 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java +++ b/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java @@ -23,7 +23,6 @@ import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.RegistryListResource; import com.volmit.iris.engine.object.common.IrisScript; -import com.volmit.iris.engine.object.dimensional.IrisDimensionIndex; import com.volmit.iris.util.collection.KList; import lombok.Data; diff --git a/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java b/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java index f3b31a799..ac0da6875 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java +++ b/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java @@ -20,20 +20,12 @@ package com.volmit.iris.core.project.loader; import com.volmit.iris.Iris; import com.volmit.iris.engine.object.common.IrisScript; -import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; -import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; import com.volmit.iris.util.io.IO; -import com.volmit.iris.util.math.M; -import com.volmit.iris.util.scheduling.ChronoLatch; -import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import java.io.File; -import java.util.concurrent.atomic.AtomicInteger; public class ScriptResourceLoader extends ResourceLoader { diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index c4825025e..83b8bf3bd 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -230,7 +230,7 @@ public class IrisComplex implements DataProvider { objectChanceStream = ProceduralStream.ofDouble((x, z) -> { if (engine.getDimension().hasFeatures(engine)) { AtomicDouble str = new AtomicDouble(1D); - for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) { str.set(Math.min(str.get(), i.getObjectChanceModifier(x, z, rng, getData()))); } @@ -241,7 +241,7 @@ public class IrisComplex implements DataProvider { }); trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D, b -> focus)).convertAware2D((b, x, z) -> { - for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) { IrisBiome bx = i.filter(x, z, b, rng); if (bx != null) { @@ -257,7 +257,7 @@ public class IrisComplex implements DataProvider { fixBiomeType(h, baseBiomeStream.get(x, z), regionStream.get(x, z), x, z, fluidHeight)) .convertAware2D((b, x, z) -> { - for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) { IrisBiome bx = i.filter(x, z, b, rng); if (bx != null) { @@ -271,7 +271,7 @@ public class IrisComplex implements DataProvider { .cache2D(cacheSize); trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D, b -> focus)).convertAware2D((b, x, z) -> { - for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) { IrisBiome bx = i.filter(x, z, b, rng); if (bx != null) { @@ -287,7 +287,7 @@ public class IrisComplex implements DataProvider { fixBiomeType(h, baseBiomeStream.get(x, z), regionStream.get(x, z), x, z, fluidHeight)) .convertAware2D((b, x, z) -> { - for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) { + for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) { IrisBiome bx = i.filter(x, z, b, rng); if (bx != null) { @@ -330,17 +330,17 @@ public class IrisComplex implements DataProvider { int m = heightf; if (engine.getDimension().isCarving() && engine.getDimension().getTerrainMode().equals(IrisTerrainMode.NORMAL)) { - if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getFramework().getTerrainActuator()).getRng(), heightf)) { + if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) { m--; - while (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getFramework().getTerrainActuator()).getRng(), heightf)) { + while (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) { m--; } } } if (engine.getDimension().isCaves()) { - KList caves = ((IrisCaveModifier) engine.getFramework().getCaveModifier()).genCaves(rx, rz, 0, 0, null); + KList caves = ((IrisCaveModifier) engine.getCaveModifier()).genCaves(rx, rz, 0, 0, null); boolean again = true; while (again) { @@ -458,7 +458,7 @@ public class IrisComplex implements DataProvider { AtomicDouble noise = new AtomicDouble(h + fluidHeight + overlayStream.get(x, z)); if (features) { - List p = engine.getFramework().getEngineParallax().forEachFeature(x, z); + List p = engine.getEngineParallax().forEachFeature(x, z); for (IrisFeaturePositional i : p) { noise.set(i.filter(x, z, noise.get(), rng, getData())); diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index d6d2f7176..5d43511c7 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -20,9 +20,18 @@ package com.volmit.iris.engine; import com.google.gson.Gson; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.events.IrisEngineHotloadEvent; +import com.volmit.iris.engine.actuator.IrisBiomeActuator; +import com.volmit.iris.engine.actuator.IrisDecorantActuator; +import com.volmit.iris.engine.actuator.IrisTerrainIslandActuator; +import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.*; +import com.volmit.iris.engine.modifier.IrisCaveModifier; +import com.volmit.iris.engine.modifier.IrisDepositModifier; +import com.volmit.iris.engine.modifier.IrisPostModifier; +import com.volmit.iris.engine.modifier.IrisRavineModifier; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer; import com.volmit.iris.engine.object.decoration.IrisDecorator; @@ -35,10 +44,10 @@ import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.io.IO; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import lombok.Getter; -import lombok.Setter; +import lombok.Data; import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.block.Biome; @@ -48,57 +57,40 @@ import org.bukkit.generator.BlockPopulator; import java.io.File; import java.io.IOException; import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; +@Data public class IrisEngine extends BlockPopulator implements Engine { - @Getter private final EngineCompound compound; - - @Getter private final EngineTarget target; - - @Getter private final IrisContext context; - - @Getter - private final EngineFramework framework; - - @Getter private final EngineEffects effects; - - @Getter private final EngineExecutionEnvironment execution; - - @Getter private final EngineWorldManager worldManager; - - @Setter - @Getter private volatile int parallelism; - - @Getter private final int index; - - @Getter private final EngineMetrics metrics; - - @Setter - @Getter private volatile int minHeight; private boolean failing; private boolean closed; private int cacheId; private final int art; - - @Getter private double maxBiomeObjectDensity; - - @Getter private double maxBiomeLayerDensity; - - @Getter private double maxBiomeDecoratorDensity; - + private final IrisComplex complex; + private final EngineParallaxManager engineParallax; + private final EngineActuator terrainNormalActuator; + private final EngineActuator terrainIslandActuator; + private final EngineActuator decorantActuator; + private final EngineActuator biomeActuator; + private final EngineModifier depositModifier; + private final EngineModifier caveModifier; + private final EngineModifier ravineModifier; + private final EngineModifier postModifier; private final AtomicCache engineData = new AtomicCache<>(); + private final AtomicBoolean cleaning; + private final ChronoLatch cleanLatch; public IrisEngine(EngineTarget target, EngineCompound compound, int index) { execution = new IrisExecutionEnvironment(this); @@ -107,7 +99,6 @@ public class IrisEngine extends BlockPopulator implements Engine { this.target = target; getData().setEngine(this); getEngineData(); - this.framework = new IrisEngineFramework(this); worldManager = new IrisWorldManager(this); this.compound = compound; minHeight = 0; @@ -121,6 +112,20 @@ public class IrisEngine extends BlockPopulator implements Engine { Iris.callEvent(new IrisEngineHotloadEvent(this)); context = new IrisContext(this); context.touch(); + this.complex = new IrisComplex(this); + this.engineParallax = new IrisEngineParallax(this); + this.terrainNormalActuator = new IrisTerrainNormalActuator(this); + this.terrainIslandActuator = new IrisTerrainIslandActuator(this); + this.decorantActuator = new IrisDecorantActuator(this); + this.biomeActuator = new IrisBiomeActuator(this); + this.depositModifier = new IrisDepositModifier(this); + this.ravineModifier = new IrisRavineModifier(this); + this.caveModifier = new IrisCaveModifier(this); + this.postModifier = new IrisPostModifier(this); + cleaning = new AtomicBoolean(false); + cleanLatch = new ChronoLatch(Math.max(10000, Math.min(IrisSettings.get().getParallax() + .getParallaxChunkEvictionMS(), IrisSettings.get().getParallax().getParallaxRegionEvictionMS()))); + } @Override @@ -180,9 +185,16 @@ public class IrisEngine extends BlockPopulator implements Engine { J.car(art); closed = true; getWorldManager().close(); - getFramework().close(); getTarget().close(); saveEngineData(); + getEngineParallax().close(); + getTerrainActuator().close(); + getDecorantActuator().close(); + getBiomeActuator().close(); + getDepositModifier().close(); + getRavineModifier().close(); + getCaveModifier().close(); + getPostModifier().close(); } @Override @@ -192,7 +204,35 @@ public class IrisEngine extends BlockPopulator implements Engine { @Override public void recycle() { - getFramework().recycle(); + if (!cleanLatch.flip()) { + return; + } + + if (cleaning.get()) { + cleanLatch.flipDown(); + return; + } + + cleaning.set(true); + + try { + getParallax().cleanup(); + getData().getObjectLoader().clean(); + } catch (Throwable e) { + Iris.reportError(e); + Iris.error("Cleanup failed!"); + e.printStackTrace(); + } + + cleaning.lazySet(false); + } + + + public EngineActuator getTerrainActuator() { + return switch (getDimension().getTerrainMode()) { + case NORMAL -> getTerrainNormalActuator(); + case ISLANDS -> getTerrainIslandActuator(); + }; } @BlockCoordinates @@ -218,18 +258,18 @@ public class IrisEngine extends BlockPopulator implements Engine { switch (getDimension().getTerrainMode()) { case NORMAL -> { - getFramework().getEngineParallax().generateParallaxArea(x >> 4, z >> 4); - getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore); - getFramework().getBiomeActuator().actuate(x, z, vbiomes, multicore); - getFramework().getCaveModifier().modify(x, z, vblocks, multicore); - getFramework().getRavineModifier().modify(x, z, vblocks, multicore); - getFramework().getPostModifier().modify(x, z, vblocks, multicore); - getFramework().getDecorantActuator().actuate(x, z, blocks, multicore); - getFramework().getEngineParallax().insertParallax(x >> 4, z >> 4, blocks); - getFramework().getDepositModifier().modify(x, z, blocks, multicore); + getEngineParallax().generateParallaxArea(x >> 4, z >> 4); + getTerrainActuator().actuate(x, z, vblocks, multicore); + getBiomeActuator().actuate(x, z, vbiomes, multicore); + getCaveModifier().modify(x, z, vblocks, multicore); + getRavineModifier().modify(x, z, vblocks, multicore); + getPostModifier().modify(x, z, vblocks, multicore); + getDecorantActuator().actuate(x, z, blocks, multicore); + getEngineParallax().insertParallax(x >> 4, z >> 4, blocks); + getDepositModifier().modify(x, z, blocks, multicore); } case ISLANDS -> { - getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore); + getTerrainActuator().actuate(x, z, vblocks, multicore); } } diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java b/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java deleted file mode 100644 index 44fdc7fde..000000000 --- a/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.engine.actuator.IrisBiomeActuator; -import com.volmit.iris.engine.actuator.IrisDecorantActuator; -import com.volmit.iris.engine.actuator.IrisTerrainIslandActuator; -import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; -import com.volmit.iris.engine.framework.*; -import com.volmit.iris.engine.modifier.IrisCaveModifier; -import com.volmit.iris.engine.modifier.IrisDepositModifier; -import com.volmit.iris.engine.modifier.IrisPostModifier; -import com.volmit.iris.engine.modifier.IrisRavineModifier; -import com.volmit.iris.util.io.ReactiveFolder; -import com.volmit.iris.util.scheduling.ChronoLatch; -import lombok.Getter; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; - -import java.util.concurrent.atomic.AtomicBoolean; - -public class IrisEngineFramework implements EngineFramework { - - @Getter - private final Engine engine; - - @Getter - private final IrisComplex complex; - - @Getter - final EngineParallaxManager engineParallax; - - @Getter - private final EngineActuator terrainNormalActuator; - - @Getter - private final EngineActuator terrainIslandActuator; - - @Getter - private final EngineActuator decorantActuator; - - @Getter - private final EngineActuator biomeActuator; - - @Getter - private final EngineModifier depositModifier; - - @Getter - private final EngineModifier caveModifier; - - @Getter - private final EngineModifier ravineModifier; - - @Getter - private final EngineModifier postModifier; - - private final AtomicBoolean cleaning; - private final ChronoLatch cleanLatch; - - public IrisEngineFramework(Engine engine) { - this.engine = engine; - this.complex = new IrisComplex(getEngine()); - this.engineParallax = new IrisEngineParallax(getEngine()); - this.terrainNormalActuator = new IrisTerrainNormalActuator(getEngine()); - this.terrainIslandActuator = new IrisTerrainIslandActuator(getEngine()); - this.decorantActuator = new IrisDecorantActuator(getEngine()); - this.biomeActuator = new IrisBiomeActuator(getEngine()); - this.depositModifier = new IrisDepositModifier(getEngine()); - this.ravineModifier = new IrisRavineModifier(getEngine()); - this.caveModifier = new IrisCaveModifier(engine); - this.postModifier = new IrisPostModifier(engine); - cleaning = new AtomicBoolean(false); - cleanLatch = new ChronoLatch(Math.max(10000, Math.min(IrisSettings.get().getParallax().getParallaxChunkEvictionMS(), IrisSettings.get().getParallax().getParallaxRegionEvictionMS()))); - } - - @Override - public synchronized void recycle() { - if (!cleanLatch.flip()) { - return; - } - - if (cleaning.get()) { - cleanLatch.flipDown(); - return; - } - - cleaning.set(true); - - try { - getEngine().getParallax().cleanup(); - getData().getObjectLoader().clean(); - } catch (Throwable e) { - Iris.reportError(e); - Iris.error("Cleanup failed!"); - e.printStackTrace(); - } - - cleaning.lazySet(false); - } - - @Override - public EngineActuator getTerrainActuator() { - return switch (getEngine().getDimension().getTerrainMode()) { - case NORMAL -> getTerrainNormalActuator(); - case ISLANDS -> getTerrainIslandActuator(); - }; - } - - @Override - public void close() { - getEngineParallax().close(); - getTerrainActuator().close(); - getDecorantActuator().close(); - getBiomeActuator().close(); - getDepositModifier().close(); - getRavineModifier().close(); - getCaveModifier().close(); - getPostModifier().close(); - } -} diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index f9f0994c3..72ac19a93 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -30,8 +30,7 @@ public class IrisEngineMantle implements EngineMantle { private final Engine engine; private final Mantle mantle; - public IrisEngineMantle(Engine engine) - { + public IrisEngineMantle(Engine engine) { this.engine = engine; this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle/" + engine.getIndex()), engine.getTarget().getHeight()); } diff --git a/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java index 629feb080..78a1c3ea9 100644 --- a/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java +++ b/src/main/java/com/volmit/iris/engine/IrisExecutionEnvironment.java @@ -24,7 +24,6 @@ import com.volmit.iris.engine.scripting.EngineExecutionEnvironment; import com.volmit.iris.engine.scripting.IrisScriptingAPI; import com.volmit.iris.util.format.C; import lombok.Data; -import org.apache.bsf.BSFEngine; import org.apache.bsf.BSFException; import org.apache.bsf.BSFManager; import org.apache.bsf.engines.javascript.JavaScriptEngine; @@ -36,8 +35,7 @@ public class IrisExecutionEnvironment implements EngineExecutionEnvironment { private final IrisScriptingAPI api; private JavaScriptEngine javaScriptEngine; - public IrisExecutionEnvironment(Engine engine) - { + public IrisExecutionEnvironment(Engine engine) { this.engine = engine; this.api = new IrisScriptingAPI(engine); this.manager = new BSFManager(); @@ -55,8 +53,7 @@ public class IrisExecutionEnvironment implements EngineExecutionEnvironment { return api; } - public void execute(String script) - { + public void execute(String script) { Iris.debug("Execute Script (void) " + C.DARK_GREEN + script); try { javaScriptEngine.exec("", 0, 0, getEngine().getData().getScriptLoader().load(script)); @@ -65,8 +62,7 @@ public class IrisExecutionEnvironment implements EngineExecutionEnvironment { } } - public Object evaluate(String script) - { + public Object evaluate(String script) { Iris.debug("Execute Script (for result) " + C.DARK_GREEN + script); try { return javaScriptEngine.eval("", 0, 0, getEngine().getData().getScriptLoader().load(script)); diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index b44d5573f..77fd87e71 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -87,13 +87,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager { looper = new Looper() { @Override protected long loop() { - if(getEngine().isClosed()) - { + if (getEngine().isClosed()) { interrupt(); } - if(getDimension().isInfiniteEnergy()) - { + if (getDimension().isInfiniteEnergy()) { energy += 1000; fixEnergy(); } @@ -138,8 +136,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } private boolean onAsyncTick() { - if(getEngine().isClosed()) - { + if (getEngine().isClosed()) { return false; } @@ -164,13 +161,9 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } if (cl.flip()) { - try - { + try { J.s(() -> precount = getEngine().getWorld().realWorld().getEntities()); - } - - catch(Throwable e) - { + } catch (Throwable e) { close(); } } @@ -213,7 +206,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { getData().getSpawnerLoader() .loadAll(getDimension().getEntitySpawners()) .shuffleCopy(RNG.r).stream().filter(this::canSpawn), - getData().getSpawnerLoader().streamAll(getEngine().getFramework().getEngineParallax() + getData().getSpawnerLoader().streamAll(getEngine().getEngineParallax() .getFeaturesInChunk(c).stream() .flatMap((o) -> o.getFeature().getEntitySpawners().stream())) .filter(this::canSpawn)) @@ -241,13 +234,9 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } } - try - { + try { spawn(c, v); - } - - catch(Throwable e) - { + } catch (Throwable e) { J.s(() -> spawn(c, v)); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index d8c80ce7b..a42fad916 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -22,6 +22,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.gui.components.RenderType; import com.volmit.iris.core.gui.components.Renderer; import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.object.basic.IrisColor; import com.volmit.iris.engine.object.biome.IrisBiome; @@ -62,6 +63,26 @@ import java.util.Arrays; import java.util.UUID; public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer, Hotloadable { + IrisComplex getComplex(); + + void recycle(); + + EngineParallaxManager getEngineParallax(); + + EngineActuator getTerrainActuator(); + + EngineActuator getDecorantActuator(); + + EngineActuator getBiomeActuator(); + + EngineModifier getCaveModifier(); + + EngineModifier getRavineModifier(); + + EngineModifier getDepositModifier(); + + EngineModifier getPostModifier(); + void close(); IrisContext getContext(); @@ -81,19 +102,15 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro void setParallelism(int parallelism); default UUID getBiomeID(int x, int z) { - return getFramework().getComplex().getBaseBiomeIDStream().get(x, z); + return getComplex().getBaseBiomeIDStream().get(x, z); } int getParallelism(); EngineTarget getTarget(); - EngineFramework getFramework(); - void setMinHeight(int min); - void recycle(); - int getIndex(); int getMinHeight(); @@ -152,7 +169,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro IrisBiome biome = getSurfaceBiome((int) x, (int) z); int height = getHeight((int) x, (int) z); double heightFactor = M.lerpInverse(0, getHeight(), height); - Color irc = region.getColor(this.getFramework().getComplex(), RenderType.BIOME); + Color irc = region.getColor(this.getComplex(), RenderType.BIOME); Color ibc = biome.getColor(this, RenderType.BIOME); Color rc = irc != null ? irc : Color.GREEN.darker(); Color bc = ibc != null ? ibc : biome.isAquatic() ? Color.BLUE : Color.YELLOW; @@ -164,7 +181,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro @BlockCoordinates @Override default IrisRegion getRegion(int x, int z) { - return getFramework().getComplex().getRegionStream().get(x, z); + return getComplex().getRegionStream().get(x, z); } @Override @@ -175,13 +192,13 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro @BlockCoordinates @Override default IrisBiome getCaveBiome(int x, int z) { - return getFramework().getComplex().getCaveBiomeStream().get(x, z); + return getComplex().getCaveBiomeStream().get(x, z); } @BlockCoordinates @Override default IrisBiome getSurfaceBiome(int x, int z) { - return getFramework().getComplex().getTrueBiomeStream().get(x, z); + return getComplex().getTrueBiomeStream().get(x, z); } @BlockCoordinates @@ -192,7 +209,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro @BlockCoordinates default int getHeight(int x, int z, boolean ignoreFluid) { - return getFramework().getEngineParallax().getHighest(x, z, getData(), ignoreFluid); + return getEngineParallax().getHighest(x, z, getData(), ignoreFluid); } @BlockCoordinates @@ -326,7 +343,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro list.clear(); } - list.addAll(r.getLootTables(getFramework().getComplex())); + list.addAll(r.getLootTables(getComplex())); } @BlockCoordinates @@ -334,8 +351,8 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro default KList getLootTables(RNG rng, Block b) { int rx = b.getX(); int rz = b.getZ(); - double he = getFramework().getComplex().getHeightStream().get(rx, rz); - PlacedObject po = getFramework().getEngine().getObjectPlacement(rx, b.getY(), rz); + double he = getComplex().getHeightStream().get(rx, rz); + PlacedObject po = getObjectPlacement(rx, b.getY(), rz); if (po != null && po.getPlacement() != null) { if (B.isStorageChest(b.getBlockData())) { @@ -345,9 +362,9 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro } } } - IrisRegion region = getFramework().getComplex().getRegionStream().get(rx, rz); - IrisBiome biomeSurface = getFramework().getComplex().getTrueBiomeStream().get(rx, rz); - IrisBiome biomeUnder = b.getY() < he ? getFramework().getComplex().getCaveBiomeStream().get(rx, rz) : biomeSurface; + IrisRegion region = getComplex().getRegionStream().get(rx, rz); + IrisBiome biomeSurface = getComplex().getTrueBiomeStream().get(rx, rz); + IrisBiome biomeUnder = b.getY() < he ? getComplex().getCaveBiomeStream().get(rx, rz) : biomeSurface; KList tables = new KList<>(); double multiplier = 1D * getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier() * biomeUnder.getLoot().getMultiplier(); injectTables(tables, getDimension().getLoot()); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java index be73f0c4f..6903159b5 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java @@ -72,15 +72,11 @@ public interface EngineComponent { return getTarget().getWorld().seed(); } - default EngineFramework getFramework() { - return getEngine().getFramework(); - } - default int getParallelism() { return getEngine().getParallelism(); } default IrisComplex getComplex() { - return getFramework().getComplex(); + return getEngine().getComplex(); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java index 662892b8e..77321ccef 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java @@ -156,7 +156,7 @@ public interface EngineCompound extends Listener, Hotloadable, DataProvider { Engine e = getEngine(i); if (e.getDimension().isBedrock()) { - int m = ((IrisTerrainNormalActuator) e.getFramework().getTerrainActuator()).getLastBedrock(); + int m = ((IrisTerrainNormalActuator) e.getTerrainActuator()).getLastBedrock(); if (f > m) { f = m; diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineFramework.java b/src/main/java/com/volmit/iris/engine/framework/EngineFramework.java deleted file mode 100644 index bf3b7c6e8..000000000 --- a/src/main/java/com/volmit/iris/engine/framework/EngineFramework.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.framework; - -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.engine.IrisComplex; -import com.volmit.iris.util.data.DataProvider; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; - -public interface EngineFramework extends DataProvider { - Engine getEngine(); - - IrisComplex getComplex(); - - EngineParallaxManager getEngineParallax(); - - default IrisData getData() { - return getComplex().getData(); - } - - default void recycle() { - getEngine().getParallax().cleanup(); - getData().getObjectLoader().clean(); - } - - EngineActuator getTerrainActuator(); - - EngineActuator getDecorantActuator(); - - EngineActuator getBiomeActuator(); - - EngineModifier getCaveModifier(); - - EngineModifier getRavineModifier(); - - EngineModifier getDepositModifier(); - - EngineModifier getPostModifier(); - - void close(); -} diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java b/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java index 6530674e0..7c4a729f8 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java @@ -74,10 +74,6 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { int getParallaxSize(); - default EngineFramework getFramework() { - return getEngine().getFramework(); - } - default ParallaxAccess getParallaxAccess() { return getEngine().getParallax(); } @@ -87,7 +83,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { } default IrisComplex getComplex() { - return getEngine().getFramework().getComplex(); + return getEngine().getComplex(); } default KList getAllRegions() { @@ -214,13 +210,13 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { KList pos = new KList<>(); for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) { - if (i.shouldFilter((x << 4) + 8, (z << 4) + 8, getEngine().getFramework().getComplex().getRng(), getData())) { + if (i.shouldFilter((x << 4) + 8, (z << 4) + 8, getEngine().getComplex().getRng(), getData())) { pos.add(i); } } for (IrisFeaturePositional i : getParallaxAccess().getMetaR(x, z).getFeatures()) { - if (i.shouldFilter((x << 4) + 8, (z << 4) + 8, getEngine().getFramework().getComplex().getRng(), getData())) { + if (i.shouldFilter((x << 4) + 8, (z << 4) + 8, getEngine().getComplex().getRng(), getData())) { pos.add(i); } } @@ -242,7 +238,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { } for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) { - if (i.shouldFilter(x, z, getEngine().getFramework().getComplex().getRng(), getData())) { + if (i.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) { pos.add(i); } } @@ -259,7 +255,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { try { for (IrisFeaturePositional k : m.getFeatures()) { - if (k.shouldFilter(x, z, getEngine().getFramework().getComplex().getRng(), getData())) { + if (k.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) { pos.add(k); } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index f1277e18c..5dc36b852 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -22,7 +22,6 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineFramework; import com.volmit.iris.engine.framework.EngineTarget; import com.volmit.iris.engine.object.common.IObjectPlacer; import com.volmit.iris.engine.object.dimensional.IrisDimension; @@ -33,8 +32,7 @@ import com.volmit.iris.util.mantle.Mantle; import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; -public interface EngineMantle extends IObjectPlacer -{ +public interface EngineMantle extends IObjectPlacer { BlockData AIR = B.get("AIR"); Mantle getMantle(); @@ -65,7 +63,7 @@ public interface EngineMantle extends IObjectPlacer @Override default void set(int x, int y, int z, BlockData d) { - getMantle().set(x,y,z,d == null ? AIR : d); + getMantle().set(x, y, z, d == null ? AIR : d); } @Override @@ -76,7 +74,7 @@ public interface EngineMantle extends IObjectPlacer @Override default BlockData get(int x, int y, int z) { - BlockData block = getMantle().get(x,y,z,BlockData.class); + BlockData block = getMantle().get(x, y, z, BlockData.class); if (block == null) { return AIR; @@ -110,8 +108,7 @@ public interface EngineMantle extends IObjectPlacer return getEngine().getDimension().isDebugSmartBore(); } - default void trim(long dur) - { + default void trim(long dur) { getMantle().trim(dur); } @@ -131,16 +128,11 @@ public interface EngineMantle extends IObjectPlacer return getEngine().getDimension(); } - default EngineFramework getFramework() { - return getEngine().getFramework(); - } - default IrisComplex getComplex() { - return getFramework().getComplex(); + return getEngine().getComplex(); } - default void close() - { + default void close() { getMantle().close(); } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/MantleSized.java b/src/main/java/com/volmit/iris/engine/mantle/MantleSized.java index 1668a182d..b6552e8f5 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/MantleSized.java +++ b/src/main/java/com/volmit/iris/engine/mantle/MantleSized.java @@ -19,5 +19,5 @@ package com.volmit.iris.engine.mantle; public interface MantleSized { - public int getMaxChunkSize(); + int getMaxChunkSize(); } diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index 303686b51..91c23922f 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -62,11 +62,11 @@ public class IrisPostModifier extends EngineAssignedModifier { @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") private void post(int currentPostX, int currentPostZ, Hunk currentData, int x, int z) { - int h = getFramework().getEngineParallax().trueHeight(x, z); - int ha = getFramework().getEngineParallax().trueHeight(x + 1, z); - int hb = getFramework().getEngineParallax().trueHeight(x, z + 1); - int hc = getFramework().getEngineParallax().trueHeight(x - 1, z); - int hd = getFramework().getEngineParallax().trueHeight(x, z - 1); + int h = getEngine().getEngineParallax().trueHeight(x, z); + int ha = getEngine().getEngineParallax().trueHeight(x + 1, z); + int hb = getEngine().getEngineParallax().trueHeight(x, z + 1); + int hc = getEngine().getEngineParallax().trueHeight(x - 1, z); + int hd = getEngine().getEngineParallax().trueHeight(x, z - 1); // Floating Nibs int g = 0; @@ -234,7 +234,7 @@ public class IrisPostModifier extends EngineAssignedModifier { IrisBiome cave = getComplex().getCaveBiomeStream().get(x, z); if (cave != null) { - for (CaveResult i : ((IrisCaveModifier) getFramework().getCaveModifier()).genCaves(x, z, 0, 0, null)) { + for (CaveResult i : ((IrisCaveModifier) getEngine().getCaveModifier()).genCaves(x, z, 0, 0, null)) { if (i.getCeiling() >= currentData.getMax2DParallelism() || i.getFloor() < 0) { continue; } diff --git a/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java b/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java index e5a1c21de..413b488e9 100644 --- a/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java +++ b/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java @@ -21,20 +21,17 @@ package com.volmit.iris.engine.object.common; import com.volmit.iris.core.project.loader.IrisRegistrant; import lombok.Data; import lombok.EqualsAndHashCode; -import org.bukkit.Bukkit; @EqualsAndHashCode(callSuper = true) @Data public class IrisScript extends IrisRegistrant { private final String source; - public IrisScript() - { + public IrisScript() { this(""); } - public IrisScript(String source) - { + public IrisScript(String source) { this.source = source; } @@ -48,8 +45,7 @@ public class IrisScript extends IrisRegistrant { return "Script"; } - public String toString() - { + public String toString() { return source; } } diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java index f2f436248..d38dc10a6 100644 --- a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java @@ -169,26 +169,19 @@ public class IrisEntity extends IrisRegistrant { public Entity spawn(Engine gen, Location at, RNG rng) { Entity ee = doSpawn(at); - if(!spawnerScript.isEmpty() && ee == null) - { - synchronized (this) - { + if (!spawnerScript.isEmpty() && ee == null) { + synchronized (this) { gen.getExecution().getAPI().setLocation(at); - try - { + try { ee = (Entity) gen.getExecution().evaluate(spawnerScript); - } - - catch(Throwable ex) - { + } catch (Throwable ex) { Iris.error("You must return an Entity in your scripts to use entity scripts!"); ex.printStackTrace(); } } } - if(ee == null) - { + if (ee == null) { return null; } @@ -313,15 +306,12 @@ public class IrisEntity extends IrisRegistrant { spawnEffect.apply(e); } - if(postSpawnScripts.isNotEmpty()) - { - synchronized (this) - { + if (postSpawnScripts.isNotEmpty()) { + synchronized (this) { gen.getExecution().getAPI().setLocation(at); gen.getExecution().getAPI().setEntity(ee); - for(String i : postSpawnScripts) - { + for (String i : postSpawnScripts) { gen.getExecution().execute(i); } } @@ -331,8 +321,7 @@ public class IrisEntity extends IrisRegistrant { } private Entity doSpawn(Location at) { - if(type.equals(EntityType.UNKNOWN)) - { + if (type.equals(EntityType.UNKNOWN)) { return null; } diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java index 371d4c138..8a811e5af 100644 --- a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java @@ -22,7 +22,6 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineFramework; import com.volmit.iris.engine.modifier.IrisCaveModifier; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MinNumber; @@ -86,12 +85,11 @@ public class IrisEntitySpawn implements IRare { Location l = switch (getReferenceSpawner().getGroup()) { case NORMAL -> new Location(c.getWorld(), x, hf + 1, z); case CAVE -> { - IrisComplex comp = gen.getFramework().getComplex(); - EngineFramework frame = gen.getFramework(); + IrisComplex comp = gen.getComplex(); IrisBiome cave = comp.getCaveBiomeStream().get(x, z); KList r = new KList<>(); if (cave != null) { - for (CaveResult i : ((IrisCaveModifier) frame.getCaveModifier()).genCaves(x, z)) { + for (CaveResult i : ((IrisCaveModifier) gen.getCaveModifier()).genCaves(x, z)) { if (i.getCeiling() >= gen.getHeight() || i.getFloor() < 0 || i.getCeiling() - 2 <= i.getFloor()) { continue; } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineStreamType.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineStreamType.java index e69675f7f..6f88ee4ef 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineStreamType.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineStreamType.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.noise; -import com.volmit.iris.engine.framework.EngineFramework; +import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.util.stream.ProceduralStream; @@ -56,13 +56,13 @@ public enum IrisEngineStreamType { @Desc("Represents the identity of regions. Each region has a unique number (very large numbers)") REGION_IDENTITY((f) -> f.getComplex().getRegionIdentityStream()); - private final Function> getter; + private final Function> getter; - IrisEngineStreamType(Function> getter) { + IrisEngineStreamType(Function> getter) { this.getter = getter; } - public ProceduralStream get(EngineFramework engine) { + public ProceduralStream get(Engine engine) { return getter.apply(engine); } } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineValueType.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineValueType.java index fc1e1c427..f7a0ecb4d 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineValueType.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisEngineValueType.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.noise; -import com.volmit.iris.engine.framework.EngineFramework; +import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.annotations.Desc; import java.util.function.Function; @@ -26,28 +26,28 @@ import java.util.function.Function; @Desc("Represents a value from the engine") public enum IrisEngineValueType { @Desc("Represents actual height of the engine") - ENGINE_HEIGHT((f) -> Double.valueOf(f.getEngine().getHeight())), + ENGINE_HEIGHT((f) -> Double.valueOf(f.getHeight())), @Desc("Represents virtual bottom of the engine in the compound. If this engine is on top of another engine, it's min height would be at the maxHeight of the previous engine + 1") - ENGINE_MIN_HEIGHT((f) -> Double.valueOf(f.getEngine().getMinHeight())), + ENGINE_MIN_HEIGHT((f) -> Double.valueOf(f.getMinHeight())), @Desc("Represents virtual top of the engine in the compound. If this engine is below another engine, it's max height would be at the minHeight of the next engine - 1") - ENGINE_MAX_HEIGHT((f) -> Double.valueOf(f.getEngine().getMaxHeight())), + ENGINE_MAX_HEIGHT((f) -> Double.valueOf(f.getMaxHeight())), @Desc("Represents the position of the engine in the dimensional compound. The bottom (first) dimension stasts at 0. Each new dimension added stacks on top with n+1 for the id.") - ENGINE_INDEX((f) -> Double.valueOf(f.getEngine().getIndex())), + ENGINE_INDEX((f) -> Double.valueOf(f.getIndex())), @Desc("The fluid height defined in the dimension file") FLUID_HEIGHT((f) -> Double.valueOf(f.getComplex().getFluidHeight())), ; - private final Function getter; + private final Function getter; - IrisEngineValueType(Function getter) { + IrisEngineValueType(Function getter) { this.getter = getter; } - public Double get(EngineFramework engine) { + public Double get(Engine engine) { return getter.apply(engine); } } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java index c393bdd3f..45c6f6c67 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java @@ -59,11 +59,11 @@ public class IrisExpressionLoad { public double getValue(RNG rng, IrisData data, double x, double z) { if (engineValue != null) { - return valueCache.aquire(() -> engineValue.get(data.getEngine().getFramework())); + return valueCache.aquire(() -> engineValue.get(data.getEngine())); } if (engineStreamValue != null) { - return streamCache.aquire(() -> engineStreamValue.get(data.getEngine().getFramework())).get(x, z); + return streamCache.aquire(() -> engineStreamValue.get(data.getEngine())).get(x, z); } if (styleValue != null) { @@ -75,11 +75,11 @@ public class IrisExpressionLoad { public double getValue(RNG rng, IrisData data, double x, double y, double z) { if (engineValue != null) { - return valueCache.aquire(() -> engineValue.get(data.getEngine().getFramework())); + return valueCache.aquire(() -> engineValue.get(data.getEngine())); } if (engineStreamValue != null) { - return streamCache.aquire(() -> engineStreamValue.get(data.getEngine().getFramework())).get(x, z); + return streamCache.aquire(() -> engineStreamValue.get(data.getEngine())).get(x, z); } if (styleValue != null) { diff --git a/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java b/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java index 43b476868..100279ece 100644 --- a/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java +++ b/src/main/java/com/volmit/iris/engine/scripting/EngineExecutionEnvironment.java @@ -21,8 +21,7 @@ package com.volmit.iris.engine.scripting; import com.volmit.iris.engine.framework.Engine; import org.apache.bsf.BSFManager; -public interface EngineExecutionEnvironment -{ +public interface EngineExecutionEnvironment { Engine getEngine(); IrisScriptingAPI getAPI(); @@ -33,8 +32,7 @@ public interface EngineExecutionEnvironment Object evaluate(String script); - default void close() - { + default void close() { } } diff --git a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java index a6671c0e8..9c19a7bb5 100644 --- a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java +++ b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java @@ -23,7 +23,6 @@ import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.core.project.loader.IrisRegistrant; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineFramework; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.object.noise.IrisExpression; @@ -41,70 +40,53 @@ public class IrisScriptingAPI { private Location location; private Entity entity; - public IrisScriptingAPI(Engine engine) - { + public IrisScriptingAPI(Engine engine) { this.engine = engine; } - public IrisData getData() - { + public IrisData getData() { return getEngine().getData(); } - public EngineFramework getFramework() - { - return getEngine().getFramework(); + public IrisComplex getComplex() { + return getEngine().getComplex(); } - public IrisComplex getComplex() - { - return getFramework().getComplex(); - } - - public long getSeed() - { + public long getSeed() { return getEngine().getTarget().getWorld().seed(); } - public double expression(String expressionName, double x, double y, double z) - { + public double expression(String expressionName, double x, double y, double z) { IrisExpression expression = getData().getExpressionLoader().load(expressionName); return expression.evaluate(getComplex().getRng(), x, y, z); } - public double expression(String expressionName, double x, double z) - { + public double expression(String expressionName, double x, double z) { IrisExpression expression = getData().getExpressionLoader().load(expressionName); return expression.evaluate(getComplex().getRng(), x, z); } - public IrisBiome getBiomeAt(int x, int z) - { + public IrisBiome getBiomeAt(int x, int z) { return getEngine().getSurfaceBiome(x, z); } - public IrisDimension getDimension() - { + public IrisDimension getDimension() { return getEngine().getDimension(); } - public void info(String log) - { + public void info(String log) { Iris.info(log); } - public void debug(String log) - { + public void debug(String log) { Iris.debug(log); } - public void warn(String log) - { + public void warn(String log) { Iris.warn(log); } - public void error(String log) - { + public void error(String log) { Iris.error(log); } } diff --git a/src/main/java/com/volmit/iris/util/context/IrisContext.java b/src/main/java/com/volmit/iris/util/context/IrisContext.java index d25065fdd..3795e955a 100644 --- a/src/main/java/com/volmit/iris/util/context/IrisContext.java +++ b/src/main/java/com/volmit/iris/util/context/IrisContext.java @@ -31,6 +31,7 @@ import lombok.Data; public class IrisContext { private static ChronoLatch cl = new ChronoLatch(60000); private static KMap context = new KMap<>(); + private final Engine engine; public static IrisContext get() { return context.get(Thread.currentThread()); @@ -50,8 +51,6 @@ public class IrisContext { } } - private final Engine engine; - public void touch() { IrisContext.touch(this); } @@ -61,6 +60,6 @@ public class IrisContext { } public IrisComplex getComplex() { - return engine.getFramework().getComplex(); + return engine.getComplex(); } } diff --git a/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java b/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java index 8d12b7fd8..81df14fa9 100644 --- a/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java +++ b/src/main/java/com/volmit/iris/util/io/ReactiveFolder.java @@ -46,7 +46,7 @@ public class ReactiveFolder { if (checkCycle % 3 == 0 ? fw.checkModified() : fw.checkModifiedFast()) { for (File i : fw.getCreated()) { - if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")|| i.getName().endsWith(".js")) { + if (i.getName().endsWith(".iob") || i.getName().endsWith(".json") || i.getName().endsWith(".js")) { modified = true; break; } @@ -54,7 +54,7 @@ public class ReactiveFolder { if (!modified) { for (File i : fw.getChanged()) { - if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")|| i.getName().endsWith(".js")) { + if (i.getName().endsWith(".iob") || i.getName().endsWith(".json") || i.getName().endsWith(".js")) { modified = true; break; } @@ -63,7 +63,7 @@ public class ReactiveFolder { if (!modified) { for (File i : fw.getDeleted()) { - if (i.getName().endsWith(".iob") || i.getName().endsWith(".json")|| i.getName().endsWith(".js")) { + if (i.getName().endsWith(".iob") || i.getName().endsWith(".json") || i.getName().endsWith(".js")) { modified = true; break; } diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java index 574c4a650..ebbd93916 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java @@ -18,10 +18,7 @@ package com.volmit.iris.util.mantle; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; -import com.volmit.iris.util.data.Varint; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.matter.IrisMatter; import com.volmit.iris.util.matter.Matter; @@ -63,8 +60,7 @@ public class MantleChunk { int s = din.readByte(); int f = din.readByte(); - for(int i = 0; i < f; i++) - { + for (int i = 0; i < f; i++) { flags.add(din.readUTF()); } @@ -75,21 +71,15 @@ public class MantleChunk { } } - public void flag(String s, boolean f) - { - if(f) - { + public void flag(String s, boolean f) { + if (f) { flags.add(s); - } - - else - { + } else { flags.remove(s); } } - public boolean isFlagged(String s) - { + public boolean isFlagged(String s) { return flags.contains(s); } @@ -162,8 +152,7 @@ public class MantleChunk { dos.writeByte(sections.length()); dos.writeByte(flags.size()); - for(String i : flags) - { + for (String i : flags) { dos.writeUTF(i); } diff --git a/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java index 35a914042..6201b08f1 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java @@ -37,10 +37,8 @@ public class ZoneMatter extends RawMatter { @Override public void setRaw(int x, int y, int z, IrisFeaturePositional t) { - for(int i = 0; i < getHeight(); i++) - { - if(get(x, i, z) == null) - { + for (int i = 0; i < getHeight(); i++) { + if (get(x, i, z) == null) { super.setRaw(x, i, z, t); break; }