mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-27 11:09:06 +00:00
Scripting engine
This commit is contained in:
@@ -29,6 +29,9 @@ public class CommandIrisStudio extends MortarCommand {
|
||||
@Command
|
||||
private CommandIrisStudioCreate create;
|
||||
|
||||
@Command
|
||||
private CommandIrisStudioExecute execute;
|
||||
|
||||
@Command
|
||||
private CommandIrisStudioOpen open;
|
||||
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<String> 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 "";
|
||||
}
|
||||
}
|
||||
@@ -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<IrisBlockData> blockLoader;
|
||||
private ResourceLoader<IrisExpression> expressionLoader;
|
||||
private ResourceLoader<IrisObject> objectLoader;
|
||||
private ResourceLoader<IrisScript> scriptLoader;
|
||||
private KMap<Class<? extends IrisRegistrant>, ResourceLoader<? extends IrisRegistrant>> loaders = new KMap<>();
|
||||
private boolean closed;
|
||||
private final File dataFolder;
|
||||
@@ -96,7 +98,11 @@ public class IrisData {
|
||||
ResourceLoader<T> r = null;
|
||||
if (registrant.equals(IrisObject.class)) {
|
||||
r = (ResourceLoader<T>) new ObjectResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName());
|
||||
} else {
|
||||
}
|
||||
else if (registrant.equals(IrisScript.class)) {
|
||||
r = (ResourceLoader<T>) new ScriptResourceLoader(dataFolder, this, rr.getFolderName(), rr.getTypeName());
|
||||
}
|
||||
else {
|
||||
r = new ResourceLoader<T>(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));
|
||||
}
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<IrisScript> {
|
||||
|
||||
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<String> 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<String> 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;
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -16,24 +16,40 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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.)
|
||||
* <p>
|
||||
* When a scripting engine is first fired up, the initialize()
|
||||
* method is called right after construction.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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 <tt>CodeBuffer</tt>.
|
||||
*
|
||||
* @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 <tt>CodeBuffer</tt>.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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.
|
||||
* <p>
|
||||
* 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.
|
||||
*
|
||||
<br>Example: "<code>240.20061006</code>"
|
||||
stands for: BSF version <code>2.4.0</code> as of <code>2006-10-06</code>.
|
||||
*
|
||||
*
|
||||
* @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 <tt>CodeBuffer</tt>.
|
||||
*
|
||||
* @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
|
||||
* <tt>CodeBuffer</tt>.
|
||||
*
|
||||
* @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
|
||||
* <tt>CodeBuffer</tt>.
|
||||
*
|
||||
* @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."
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# 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
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 = "<STDIN>";
|
||||
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: "
|
||||
+ "<If -in is specified and -lang");
|
||||
System.err.println(
|
||||
" "
|
||||
+ " is not, attempt to determine");
|
||||
System.err.println(
|
||||
" "
|
||||
+ " language from file extension;");
|
||||
System.err.println(
|
||||
" "
|
||||
+ " otherwise, -lang is required.>");
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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, "<event-script>", 0, 0,
|
||||
argv[5].toString ());
|
||||
} catch (BSFException e) {
|
||||
e.printStackTrace ();
|
||||
interp.setResult ("got BSF exception: " + e.getMessage ());
|
||||
throw new TclException (TCL.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
* <p>
|
||||
*
|
||||
* @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 ("<function call>", 0, 0, tclScript.toString ());
|
||||
}
|
||||
/**
|
||||
* Declare a bean
|
||||
*/
|
||||
public void declareBean (BSFDeclaredBean bean) throws BSFException {
|
||||
String expr = "set " + bean.name + " [bsf lookupBean \"" + bean.name +
|
||||
"\"]";
|
||||
eval ("<declare bean>", 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 ("<undeclare bean>", 0, 0, "set " + bean.name + " \"\"");
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
* <p>
|
||||
* 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:
|
||||
* <pre>
|
||||
* <code>
|
||||
* 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
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
* $$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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* <h2>Hazards:</h2>
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* ALSO NOTE that it is your responsibility to return an object, or null in
|
||||
* lieu thereof!
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* @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.
|
||||
* <p>
|
||||
* 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).
|
||||
* <p>
|
||||
* Nobody knows whether javac is threadsafe.
|
||||
* I'm going to serialize access to protect it.
|
||||
* <p>
|
||||
* 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; i<args.length; ++i) {
|
||||
argtypes[i]=args[i].getClass();
|
||||
}
|
||||
Method m = MethodUtils.getMethod(javaclass, method, argtypes);
|
||||
retval = m.invoke(null, args);
|
||||
}
|
||||
}
|
||||
catch(Exception e) {
|
||||
throw new BSFException (BSFException.REASON_IO_ERROR, e.getMessage ());
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
private GeneratedFile openUniqueFile(String directory,String prefix,String suffix) {
|
||||
File file = 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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
* <p>
|
||||
* 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 <peller@lotus.com>
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
@@ -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 <bckfnn@worldonline.dk>
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
* <p>
|
||||
* 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:
|
||||
* <pre>
|
||||
* <code>
|
||||
* class $$CLASSNAME$$;
|
||||
* method BSFNetRexxEngineEntry(bsf=com.volmit.iris.util.bsf.BSFManager) public static;
|
||||
* </code>
|
||||
* </pre>
|
||||
* $$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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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".
|
||||
* <p>
|
||||
* <h2>Hazards:</h2>
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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<args.length;++i)
|
||||
argtypes[i]=args[i].getClass();
|
||||
|
||||
Method m=MethodUtils.getMethod(rexxclass, method, argtypes);
|
||||
retval=m.invoke(null,args);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.error("NetRexxEngine: ERROR: rexxclass==null!");
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace ();
|
||||
if (e instanceof InvocationTargetException)
|
||||
{
|
||||
Throwable t = ((InvocationTargetException)e).getTargetException ();
|
||||
t.printStackTrace ();
|
||||
}
|
||||
throw new BSFException (BSFException.REASON_IO_ERROR,
|
||||
e.getMessage (),
|
||||
e);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
public void declareBean (BSFDeclaredBean bean) throws BSFException {}
|
||||
/**
|
||||
* Override impl of execute. In NetRexx, methods which do not wish
|
||||
* to return a value should be invoked via exec, which will cause them
|
||||
* to be generated without the "returns" clause.
|
||||
* Those which wish to return a value should call eval instead.
|
||||
* which will add "returns java.lang.Object" to the header.
|
||||
*
|
||||
* Note: It would be nice to have the "real" return type avaialable, so
|
||||
* we could do something more type-safe than Object, and so we could
|
||||
* return primitive types without having to enclose them in their
|
||||
* object wrappers. BSF does not currently support that concept.
|
||||
*/
|
||||
public Object eval (String source, int lineNo, int columnNo,
|
||||
Object script)
|
||||
throws BSFException
|
||||
{
|
||||
return execEvalShared(source, lineNo, columnNo, script,true);
|
||||
}
|
||||
/**
|
||||
* Override impl of execute. In NetRexx, methods which do not wish
|
||||
* to return a value should be invoked via exec, which will cause them
|
||||
* to be generated without the "returns" clause.
|
||||
* Those which wish to return a value should call eval instead.
|
||||
* which will add "returns java.lang.Object" to the header.
|
||||
*/
|
||||
public void exec (String source, int lineNo, int columnNo,
|
||||
Object script)
|
||||
throws BSFException
|
||||
{
|
||||
execEvalShared(source, lineNo, columnNo, script,false);
|
||||
}
|
||||
/**
|
||||
* This is shared code for the exec() and eval() operations. It will
|
||||
* evaluate a string containing a NetRexx method body -- which may be
|
||||
* as simple as a single return statement.
|
||||
* It should store the "bsf" handle where the
|
||||
* script can get to it, for callback purposes.
|
||||
* <p>
|
||||
* 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).
|
||||
* <p>
|
||||
* 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(endpoint<script.length())
|
||||
changed.append(script.substring(endpoint));
|
||||
script=changed.toString();
|
||||
}
|
||||
}
|
||||
|
||||
BSFDeclaredBean tempBean;
|
||||
String className;
|
||||
|
||||
for (int i = 0; i < declaredBeans.size (); i++)
|
||||
{
|
||||
tempBean = (BSFDeclaredBean) declaredBeans.elementAt (i);
|
||||
className = StringUtils.getClassName (tempBean.type);
|
||||
|
||||
gf.fos.write ((tempBean.name + " =" + className + " bsf.lookupBean(\"" +
|
||||
tempBean.name + "\");").getBytes());
|
||||
}
|
||||
|
||||
if(returnsObject)
|
||||
gf.fos.write("return ".getBytes());
|
||||
|
||||
// Copy the input to the file.
|
||||
// Assumes all available -- probably mistake, but same as
|
||||
// other engines.
|
||||
gf.fos.write(script.getBytes());
|
||||
gf.fos.close();
|
||||
|
||||
logger.debug("NetRexxEngine: wrote temp file " +
|
||||
gf.file.getPath () + ", now compiling");
|
||||
|
||||
// Compile through Java to .class file
|
||||
String command=gf.file.getPath(); //classname;
|
||||
if (logger.isDebugEnabled()) {
|
||||
command += " -verbose4";
|
||||
} else {
|
||||
command += " -noverbose";
|
||||
command += " -noconsole";
|
||||
}
|
||||
|
||||
netrexx.lang.Rexx cmdline= new netrexx.lang.Rexx(command);
|
||||
int retValue;
|
||||
|
||||
// May not be threadsafe. Serialize access on static object:
|
||||
synchronized(serializeCompilation)
|
||||
{
|
||||
// compile to a .java file
|
||||
retValue =
|
||||
COM.ibm.netrexx.process.NetRexxC.main(cmdline,
|
||||
new PrintWriter(System.err));
|
||||
}
|
||||
|
||||
// Check if there were errors while compiling the Rexx code.
|
||||
if (retValue == 2)
|
||||
{
|
||||
throw new BSFException(BSFException.REASON_EXECUTION_ERROR,
|
||||
"There were NetRexx errors.");
|
||||
}
|
||||
|
||||
// Load class.
|
||||
logger.debug("NetRexxEngine: loading class "+classname);
|
||||
rexxclass=EngineUtils.loadClass (mgr, classname);
|
||||
|
||||
// Stash class for reuse
|
||||
codeToClass.put(basescript,rexxclass);
|
||||
}
|
||||
|
||||
Object[] args={mgrfuncs};
|
||||
retval=callStatic(rexxclass, "BSFNetRexxEngineEntry",args);
|
||||
}
|
||||
catch (BSFException e)
|
||||
{
|
||||
// Just forward the exception on.
|
||||
throw e;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace ();
|
||||
if (e instanceof InvocationTargetException)
|
||||
{
|
||||
Throwable t = ((InvocationTargetException)e).getTargetException ();
|
||||
t.printStackTrace ();
|
||||
}
|
||||
throw new BSFException (BSFException.REASON_IO_ERROR,
|
||||
e.getMessage (), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Cleanup: delete the .nrx and .class files
|
||||
// (if any) generated by NetRexx Trace requests.
|
||||
|
||||
if(gf!=null && gf.file!=null && gf.file.exists())
|
||||
gf.file.delete(); // .nrx file
|
||||
|
||||
if(classname!=null)
|
||||
{
|
||||
// Generated src
|
||||
File file=new File(tempDir+File.separatorChar+classname+".java");
|
||||
if(file.exists())
|
||||
file.delete();
|
||||
|
||||
// Generated class
|
||||
file=new File(classname+".class");
|
||||
if(file.exists())
|
||||
file.delete();
|
||||
|
||||
// Can this be done without disrupting trace?
|
||||
file=new File(tempDir+File.separatorChar+classname+".crossref");
|
||||
if(file.exists())
|
||||
file.delete();
|
||||
|
||||
// Search for and clean up minor classes, classname$xxx.class
|
||||
file=new File(tempDir);
|
||||
minorPrefix=classname+"$"; // Indirect arg to filter
|
||||
String[] minor_classfiles=
|
||||
file.list(
|
||||
// ANONYMOUS CLASS for filter:
|
||||
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)
|
||||
;
|
||||
}
|
||||
}
|
||||
);
|
||||
if(minor_classfiles!=null)
|
||||
for(int i=minor_classfiles.length;i>0;)
|
||||
{
|
||||
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 {}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
* <p>
|
||||
*
|
||||
* @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(...).");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
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
|
||||
*
|
||||
* <a
|
||||
* href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -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, "<event-binding>", 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);
|
||||
}
|
||||
}
|
||||
@@ -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 <em>Bean</em> 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;
|
||||
}
|
||||
}
|
||||
@@ -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 <code>CodeBuffer</code> 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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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 <code>IndentWriter</code> object behaves the same as a
|
||||
* <code>PrintWriter</code> 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 <code>PrintWriter</code> constructor
|
||||
* with the same signature.
|
||||
*/
|
||||
public IndentWriter(OutputStream out)
|
||||
{
|
||||
super(out);
|
||||
}
|
||||
/**
|
||||
* Forwards its arguments to the <code>PrintWriter</code> constructor
|
||||
* with the same signature.
|
||||
*/
|
||||
public IndentWriter(OutputStream out, boolean autoFlush)
|
||||
{
|
||||
super(out, autoFlush);
|
||||
}
|
||||
/**
|
||||
* Forwards its arguments to the <code>PrintWriter</code> constructor
|
||||
* with the same signature.
|
||||
*/
|
||||
public IndentWriter(Writer out)
|
||||
{
|
||||
super(out);
|
||||
}
|
||||
/**
|
||||
* Forwards its arguments to the <code>PrintWriter</code> 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);
|
||||
}
|
||||
}
|
||||
@@ -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 <string.h>
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#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, "<init>", "(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, "<init>", "(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, "<init>", "(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, "<init>", "(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, "<init>", "(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, "<init>", "(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, "<init>", "(D)V");
|
||||
return (*jenv)->NewObject (jenv, classobj, constructor, (jdouble) val);
|
||||
}
|
||||
@@ -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 <jni.h>
|
||||
#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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;i<parms.length;++i)
|
||||
if(!isMethodConvertable(parms[i],args[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
/** Internal subroutine for getEntryPoint(): Format arguments as a
|
||||
string describing the function being searched for. Used in
|
||||
verbose exceptions. */
|
||||
private static String callToString(Class targetClass,String methodName,
|
||||
Class[] argTypes,boolean isStaticReference)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
if(isStaticReference)
|
||||
buf.append("static ");
|
||||
buf.append(StringUtils.getClassName(targetClass));
|
||||
if(methodName!=null)
|
||||
buf.append(".").append(methodName);
|
||||
buf.append("(");
|
||||
if (argTypes != null && argTypes.length>0) {
|
||||
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<methods.length;++i)
|
||||
{
|
||||
Object mi=methods[i];
|
||||
if (
|
||||
// 15.11.2.1 ACCESSIBLE: Method is public.
|
||||
Modifier.isPublic(entryGetModifiers(mi))
|
||||
&&
|
||||
// 15.11.2.1 APPLICABLE: Right method name (or c'tor)
|
||||
(methodName==null || entryGetName(mi).equals(methodName) )
|
||||
&&
|
||||
// 15.11.2.1 APPLICABLE: Parameters match arguments
|
||||
areMethodConvertable(entryGetParameterTypes(mi),argTypes)
|
||||
)
|
||||
// 15.11.2.2 MORE SPECIFIC displace less specific.
|
||||
best.addItem(mi);
|
||||
}
|
||||
|
||||
// May throw NoSuchMethodException; we pass in info needed to
|
||||
// create a useful exception
|
||||
m=best.getMostSpecific(targetClass,methodName,argTypes,isStaticReference);
|
||||
|
||||
// 15.11.3 APPROPRIATE: Class invocation can call only static
|
||||
// methods. Note that the defined order of evaluation permits a
|
||||
// call to be resolved to an inappropriate method and then
|
||||
// rejected, rather than finding the best of the appropriate
|
||||
// methods.
|
||||
//
|
||||
// Constructors are never static, so we don't test them.
|
||||
if(m==null)
|
||||
{
|
||||
throw new NoSuchMethodException (callToString(targetClass,
|
||||
methodName,
|
||||
argTypes,
|
||||
isStaticReference)+
|
||||
" -- no signature match");
|
||||
}
|
||||
|
||||
if( methodName!=null &&
|
||||
isStaticReference &&
|
||||
!Modifier.isStatic(entryGetModifiers(m)) )
|
||||
{
|
||||
throw new NoSuchMethodException (callToString(targetClass,
|
||||
methodName,
|
||||
argTypes,
|
||||
isStaticReference)+
|
||||
" resolved to instance: "+m);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* Class.getMethod() 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.
|
||||
|
||||
This version more closely resembles Class.getMethod() -- we always
|
||||
ask the Class for the method. It differs in testing for
|
||||
appropriateness before returning the method; if the query is
|
||||
being made via a static reference, only static methods will be
|
||||
found and returned. */
|
||||
static public Method getMethod(Class target,String methodName,
|
||||
Class[] argTypes,boolean isStaticReference)
|
||||
throws SecurityException, NoSuchMethodException
|
||||
{
|
||||
return (Method)getEntryPoint(target,methodName,argTypes,isStaticReference);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Class.getMethod() 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.
|
||||
*
|
||||
* This version emulates the compiler behavior by allowing lookup to
|
||||
* be performed against either a class or an instance -- classname.foo()
|
||||
* must be a static method call, instance.foo() can invoke either static
|
||||
* or instance methods.
|
||||
*
|
||||
* @param target object on which call is to be made
|
||||
* @param methodName name of method I'm lookin' for
|
||||
* @param argTypes array of argument types of method
|
||||
*
|
||||
* @return the desired method
|
||||
*
|
||||
* @exception SecurityException if security violation
|
||||
* @exception NoSuchMethodException if no such method
|
||||
*/
|
||||
static public Method getMethod(Object target,String methodName,
|
||||
Class[] argTypes)
|
||||
throws SecurityException, NoSuchMethodException
|
||||
{
|
||||
boolean staticRef=target instanceof Class;
|
||||
return getMethod( staticRef ? (Class)target : target.getClass(),
|
||||
methodName,argTypes,staticRef);
|
||||
}
|
||||
/** Determine whether a given type can accept assignments of another
|
||||
type. Note that class.isAssignable() is _not_ a complete test!
|
||||
(This method is not needed by getMethod() or getConstructor(), but
|
||||
is provided as a convenience for other users.)
|
||||
|
||||
parm: The type given in the method's signature.
|
||||
arg: The type we want to pass in.
|
||||
|
||||
Legal ASSIGNMENT CONVERSIONS (5.2) are METHOD CONVERSIONS (5.3)
|
||||
plus implicit narrowing of int to byte, short or char. */
|
||||
static private boolean isAssignmentConvertable(Class parm,Class arg)
|
||||
{
|
||||
return
|
||||
(arg.equals(Integer.TYPE) &&
|
||||
(parm.equals(Byte.TYPE) ||
|
||||
parm.equals(Short.TYPE) ||
|
||||
parm.equals(Character.TYPE)
|
||||
)
|
||||
) ||
|
||||
isMethodConvertable(parm,arg);
|
||||
}
|
||||
/** Determine whether a given method parameter type can accept
|
||||
arguments of another type.
|
||||
|
||||
parm: The type given in the method's signature.
|
||||
arg: The type we want to pass in.
|
||||
|
||||
Legal METHOD CONVERSIONS (5.3) are Identity, Widening Primitive
|
||||
Conversion, or Widening Reference Conversion. NOTE that this is a
|
||||
subset of the legal ASSIGNMENT CONVERSIONS (5.2) -- in particular,
|
||||
we can't implicitly narrow int to byte, short or char.
|
||||
|
||||
SPECIAL CASE: In order to permit invoking methods with literal
|
||||
"null" values, setting the arg Class to null will be taken as a
|
||||
request to match any Class type. POSSIBLE PROBLEM: This may match
|
||||
a primitive type, which really should not accept a null value... but
|
||||
I'm not sure how best to distinguish those, short of enumerating them
|
||||
*/
|
||||
static private boolean isMethodConvertable(Class parm, Class arg)
|
||||
{
|
||||
if (parm.equals(arg)) // If same class, short-circuit now!
|
||||
return true;
|
||||
|
||||
// Accept any type EXCEPT primitives (which can't have null values).
|
||||
if (arg == null)
|
||||
{
|
||||
return !parm.isPrimitive();
|
||||
}
|
||||
|
||||
// Arrays are convertable if their elements are convertable
|
||||
// ????? Does this have to be done before isAssignableFrom, or
|
||||
// does it successfully handle arrays of primatives?
|
||||
while(parm.isArray())
|
||||
{
|
||||
if(!arg.isArray())
|
||||
return false; // Unequal array depth
|
||||
else
|
||||
{
|
||||
parm=parm.getComponentType();
|
||||
arg=arg.getComponentType();
|
||||
}
|
||||
}
|
||||
if(arg.isArray())
|
||||
return false; // Unequal array depth
|
||||
|
||||
// Despite its name, the 1.1.6 docs say that this function does
|
||||
// NOT return true for all legal ASSIGNMENT CONVERSIONS
|
||||
// (5.2):
|
||||
// "Specifically, this method tests whether the type
|
||||
// represented by the specified class can be converted
|
||||
// to the type represented by this Class object via
|
||||
// an identity conversion or via a widening reference
|
||||
// conversion."
|
||||
if(parm.isAssignableFrom(arg))
|
||||
return true;
|
||||
|
||||
// That leaves us the Widening Primitives case. Four possibilities:
|
||||
// void (can only convert to void), boolean (can only convert to boolean),
|
||||
// numeric (which are sequenced) and char (which inserts itself into the
|
||||
// numerics by promoting to int or larger)
|
||||
|
||||
if(parm.equals(Void.TYPE) || parm.equals(Boolean.TYPE) ||
|
||||
arg.equals(Void.TYPE) || arg.equals(Boolean.TYPE))
|
||||
return false;
|
||||
|
||||
Class[] primTypes={ Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE,
|
||||
Long.TYPE, Float.TYPE, Double.TYPE };
|
||||
int parmscore,argscore;
|
||||
|
||||
for(parmscore=0;parmscore<primTypes.length;++parmscore)
|
||||
if (parm.equals(primTypes[parmscore]))
|
||||
break;
|
||||
if(parmscore>=primTypes.length)
|
||||
return false; // Off the end
|
||||
|
||||
for(argscore=0;argscore<primTypes.length;++argscore)
|
||||
if (arg.equals(primTypes[argscore]))
|
||||
break;
|
||||
if(argscore>=primTypes.length)
|
||||
return false; // Off the end
|
||||
|
||||
// OK if ordered AND NOT char-to-smaller-than-int
|
||||
return (argscore<parmscore && (argscore!=0 || parmscore>2) );
|
||||
}
|
||||
}
|
||||
@@ -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 <code>ObjInfo</code> 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;
|
||||
}
|
||||
}
|
||||
@@ -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 <em>ObjectRegistry</em> is used to do name-to-object reference lookups.
|
||||
* If an <em>ObjectRegistry</em> is passed as a constructor argument, then this
|
||||
* <em>ObjectRegistry</em> 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 <em>ObjectRegistry</em>.
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <code>ScriptSymbolTable</code> object is used by a <code>CodeBuffer</code>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -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 <code>numberOfChars</code> theChars.
|
||||
*
|
||||
* @return a string consisting of <code>numberOfChars</code> 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();
|
||||
}
|
||||
}
|
||||
@@ -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 <code>CodeFormatter</code> bean can be used.
|
||||
* <p>
|
||||
* The CFDriver is a stand-alone tool that will instantiate a
|
||||
* <code>CodeFormatter</code> bean, configure it according to your
|
||||
* command-line arguments, and invoke the formatting. Since the
|
||||
* default source of input is <code>stdin</code>, and the default
|
||||
* target for output is <code>stdout</code>, a <code>CFDriver</code>
|
||||
* 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 <code>CodeFormatter</code>.
|
||||
*<p>
|
||||
* Usage:
|
||||
*<code><pre>
|
||||
* java org.apache.cf.CFDriver [args]
|
||||
*<p>
|
||||
* args:
|
||||
*<p>
|
||||
* [-in fileName] default: <STDIN>
|
||||
* [-out fileName] default: <STDOUT>
|
||||
* [-maxLine length] default: 74
|
||||
* [-step size] default: 2
|
||||
* [-delim group] default: (+
|
||||
* [-sdelim group] default: ,
|
||||
*</pre></code>
|
||||
*/
|
||||
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: <STDIN>");
|
||||
System.out.println(" [-out fileName] default: <STDOUT>");
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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 <code>CodeFormatter</code> 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 <code>indentationStep</code> property.
|
||||
* To create and use a <code>CodeFormatter</code>, you simply instantiate a
|
||||
* new <code>CodeFormatter</code> bean, and invoke
|
||||
* <code>formatCode(Reader source, Writer target)</code> 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 <code>source</code>, and writes the formatted
|
||||
* code to <code>target</code>.
|
||||
*
|
||||
* @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 <code>"(+"</code>.
|
||||
* <p>
|
||||
* 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 <em>first character on the following line</em>.
|
||||
* A quotation mark, <code>"</code> or <code>'</code>, 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 <code>2</code>.
|
||||
* <p>
|
||||
* 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
|
||||
* <code>74</code>.
|
||||
* <p>
|
||||
* 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 <code>","</code>.
|
||||
* <p>
|
||||
* 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 <em>last character on the current line</em>.
|
||||
* A quotation mark, <code>"</code> or <code>'</code>, 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <em>EventAdapter</em> 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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <em>EventAdapterImpl</em> 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;
|
||||
}
|
||||
}
|
||||
@@ -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 <em>EventAdapterRegistry</em> 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 <code>dynamic</code> property
|
||||
* to <code>false</code> to disable this feature.
|
||||
* <p>
|
||||
* 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 <tt>a.b.c.FooListener</tt>,
|
||||
* it loads an adapter of type
|
||||
* <tt>com.volmit.iris.util.bsf.util.event.adapters.a_b_c_FooAdapter</tt>.
|
||||
* If both the loading and the dynamic generation fail, then a
|
||||
* <code>null</code> is returned.
|
||||
* <p>
|
||||
*
|
||||
* @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
|
||||
* <code>true</code>.
|
||||
* <p>
|
||||
* If the <code>dynamic</code> property is set to true, and the
|
||||
* <code>ClassLoader</code> 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
/**
|
||||
* <em>EventProcessor</em> 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;
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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});
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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,"<init>");
|
||||
|
||||
// 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); // "<init>" "()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 "<init>"
|
||||
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 <init> (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;
|
||||
}
|
||||
}
|
||||
@@ -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 <em>TypeConvertor</em> 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 ();
|
||||
}
|
||||
@@ -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 <em>TypeConvertorRegistry</em> 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user