我正在加载groovy脚本,并且需要以下类:
import java.util.function.Function
import java.util.function.Supplier
class MaskingPrintStream extends PrintStream {
private final Function<String,String> subFunction
private final Supplier<String> secretText
public MaskingPrintStream(PrintStream out, Supplier<String> secretText, Function<String,String> subFunction) {
super(out);
this.subFunction = subFunction;
this.secretText = secretText;
}
@Override
public void write(byte b[], int off, int len) {
String out = new String(b,off,len);
String secret = secretText.get();
byte[] dump = out.replace(secret, subFunction.apply(secret)).getBytes();
super.write(dump,0,dump.length);
}
}
现在我将其保存在名为MaskingPrintStream.groovy
的文件中。但是,通过这样做,我实际上只能将此类作为默认创建的对应于文件名的类的内部类来访问。
我想要要工作的是这样的代码:
def stream = evaluate(new File(ClassLoader.getSystemResource('MaskingPrintStream.groovy').file))
但是正如您所看到的,我需要在准备好之前给它一些值。也许我可以将类加载到JVM中(不确定如何从另一个常规脚本中加载),然后以老式方式实例化它?
另一个问题是:如何设置它,以便没有嵌套的类安排?
答案 0 :(得分:1)
groovy.lang.Script#evaluate(java.lang.String)
的用途有些不同。
对于您的情况,您需要使用groovy.lang.GroovyClassLoader
,它能够从源代码解析groovy类,进行编译和加载。这是您的代码示例:
def groovyClassLoader = new GroovyClassLoader(this.class.classLoader) // keep for loading other classes as well
groovyClassLoader.parseClass('MaskingPrintStream.groovy')
def buf = new ByteArrayOutputStream()
def maskingStream = new MaskingPrintStream(new PrintStream(buf), { 'secret' }, { 'XXXXX' })
maskingStream.with {
append 'some text '
append 'secret '
append 'super-duper secret '
append 'other text'
}
maskingStream.close()
println "buf = ${buf}"
它在bash shell中产生的输出:
> ./my-script.groovy
buf = some text XXXXX super-duper XXXXX other text