gpt4 book ai didi

java - 如何为 r.js 提供伪文件系统?

转载 作者:行者123 更新时间:2023-11-30 18:14:51 25 4
gpt4 key购买 nike

好的,所以 r.js可以在 Rhino 上运行.这很棒。

做它需要做的事情。

在犀牛上它基本上使用java.io.File , java.io.FileOutputStreamjava.io.FileInputStream实现它需要做的文件系统修改。

(背景:我致力于为基于 Maven 的 Java/Javascript 开发人员提供更好的开发体验。作为 Maven,既有约定俗成的力量,也有固执己见的力量。您可以在 jszip.org 查看进展。)

所以我想做的是让磁盘结构神奇地显示为虚拟文件系统。

所以在磁盘上我们会有这样的结构:

/
/module1/src/main/js/controllers/controller.js
/module2/src/main/js/models/model.js
/module3/src/main/js/views/view.js
/webapp/src/build/js/profile.js
/webapp/src/main/js/main.js
/webapp/src/main/webapp/index.html

/webapp/src/build/js/profile.js应该看起来像这样:

({
appDir: "src",
baseUrl:".",
dir: "target",
optimize: "closure",
modules:[
{
name:"main"
}
]
})

这样

  • 当 r.js 请求 new File("src/main.js") 时其实我给new File("/webapp/src/main/js/main.js")

  • 当它要求 new File("profile.js") 时我给new File("/webapp/src/build/js/profile.js")

  • 当它要求 new File("controllers/controller.js") 时我给new File("/module1/src/main/js/controllers/controller.js")

  • 当它要求 new File("target") 时我给new File("/webapp/target/webapp-1.0-SNAPSHOT") .

我编写所需的三个模拟类没有问题,即用于代替 java.io.File 的模拟类, java.io.FileInputStreamjava.io.FileOutputStream ,

一些问题比如this有指向诸如 ClassShutter 之类的东西的答案,我可以看到我可以像这样使用它:

        context.setClassShutter(new ClassShutter() {
public boolean visibleToScripts(String fullClassName) {
if (File.class.getName().equals(fullClassName)) return false;
if (FileOutputStream.class.getName().equals(fullClassName)) return false;
if (FileInputStream.class.getName().equals(fullClassName)) return false;
return true;
}
});

隐藏原来的实现。

然后问题是让 Rhino 解决沙盒中的等价物......我不断得到

TypeError: [JavaPackage java.io.File] is not a function, it is object.

即使我在调用前加上 java.io.File = org.jszip.rhino.SandboxFile 的前缀将我的沙盒实现映射到现在丢失的 java.io.File

我什至可以考虑在加载的 r.js 上使用搜索和替换文件只是在编译之前......但我觉得必须有更好的方法。

有没有人有任何提示?

最佳答案

好的,经过大量实验,这似乎是这样做的方法:

Scriptable scope = context.newObject(global);
scope.setPrototype(global);
scope.setParentScope(null);

NativeJavaTopPackage $packages = (NativeJavaTopPackage) global.get("Packages");
NativeJavaPackage $java = (NativeJavaPackage) $packages.get("java");
NativeJavaPackage $java_io = (NativeJavaPackage) $java.get("io");

ProxyNativeJavaPackage proxy$java = new ProxyNativeJavaPackage($java);
ProxyNativeJavaPackage proxy$java_io = new ProxyNativeJavaPackage($java_io);
proxy$java_io.put("File", scope, get(scope, "Packages." + PseudoFile.class.getName()));
proxy$java_io.put("FileInputStream", scope,
get(scope, "Packages." + PseudoFileInputStream.class.getName()));
proxy$java_io.put("FileOutputStream", scope,
get(scope, "Packages." + PseudoFileOutputStream.class.getName()));
proxy$java.put("io", scope, proxy$java_io);
scope.put("java", scope, proxy$java);

有一个辅助方法:

private static Object get(Scriptable scope, String name) {
Scriptable cur = scope;
for (String part : StringUtils.split(name, ".")) {
Object next = cur.get(part, scope);
if (next instanceof Scriptable) {
cur = (Scriptable) next;
} else {
return null;
}
}
return cur;
}

ProxyNativeJavaPackage 是这样的

public class ProxyNativeJavaPackage extends ScriptableObject implements Serializable {
static final long serialVersionUID = 1L;

protected final NativeJavaPackage delegate;
private final Map<String, Object> mutations = new HashMap<String, Object>();

public ProxyNativeJavaPackage(NativeJavaPackage delegate) {
delegate.getClass();
this.delegate = delegate;
}

@Override
public String getClassName() {
return delegate.getClassName();
}

@Override
public boolean has(String id, Scriptable start) {
return mutations.containsKey(id) ? mutations.get(id) != null : delegate.has(id, start);
}

@Override
public boolean has(int index, Scriptable start) {
return delegate.has(index, start);
}

@Override
public void put(String id, Scriptable start, Object value) {
mutations.put(id, value);
}

@Override
public void put(int index, Scriptable start, Object value) {
delegate.put(index, start, value);
}

@Override
public Object get(String id, Scriptable start) {
if (mutations.containsKey(id)) {
return mutations.get(id);
}
return delegate.get(id, start);
}

@Override
public Object get(int index, Scriptable start) {
return delegate.get(index, start);
}

@Override
public Object getDefaultValue(Class<?> ignored) {
return toString();
}

@Override
public String toString() {
return delegate.toString();
}

@Override
public boolean equals(Object obj) {
if (obj instanceof ProxyNativeJavaPackage) {
ProxyNativeJavaPackage that = (ProxyNativeJavaPackage) obj;
return delegate.equals(that.delegate) && mutations.equals(that.mutations);
}
return false;
}

@Override
public int hashCode() {
return delegate.hashCode();
}
}

这仍然在 Packages.java.io.File 等处留下原始类,但是对于 r.js 要求,这已经足够了,并且应该可以用于其他人将此技巧扩展到一般情况。

关于java - 如何为 r.js 提供伪文件系统?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13569734/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com