如何编译Groovy源文件,但不是来自文件系统 [英] How compile Groovy source but not from filesystem

查看:128
本文介绍了如何编译Groovy源文件,但不是来自文件系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用GroovyClassLoader.parseClass(s​​rc)编译单个groovy源代码模块in fly,并且一切正常。

但问题出在这个源模块导入其他类,这些还没有编译。传统的编译,当我开始编译一个源,但其他需要和准备在源代码路径,编译也。



我如何使用GroovyClassLoader与目标编译所有其他所需来源不是从FILESYSYSTEM。
我的源代码例如在数据库中,远程http通过URI等。

解决方案

关键是制作自定义网址处理 - 您必须实施 URLStreamHandler URLConnection

如果你是谷歌,那么关于如何实现流处理程序和连接类有一些很好的文档 - 但是对于你正在做的事情,你只需要虚拟实现。



这里有一些源代码来引导你 - 它演示了如何连接组件。如果你提供了lookupScripCodeWithJDBCor的一些实现,那么你将会很好的去做。

  import groovy.lang.GroovyResourceLoader; 
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
导入java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;

public class CustomGroovyResourceLoader实现GroovyResourceLoader {

private final GroovyResourceLoader parentLoader;

public CustomGroovyResourceLoader(GroovyResourceLoader parentLoader){
this.parentLoader = parentLoader;
}

@Override
public URL loadGroovySource(String filename)throws MalformedURLException {
URL resourceURL = null;

if(parentLoader!= null){
resourceURL = parentLoader.loadGroovySource(filename);
}

if(resourceURL == null){
resourceURL = createURL(filename);
}

返回resourceURL;
}

public URL createURL(String resourceName)抛出MalformedURLException {

字符串scriptSourceCode = lookupScripCodeWithJDBCorWhatever(resourceName);

返回新的URL(null,groovy:///+ resourceName,
新的GroovyResourceStreamHandler(scriptSourceCode));



private String lookupScripCodeWithJDBCorWhatever(String resourceName){

// TODO:blah blah blah
return null;
}

类GroovyResourceConnection扩展URLConnection {

private final String urlData;

保护GroovyResourceConnection(URL url,字符串逻辑){
super(url);
this.urlData =逻辑;

$ b @Override
public void connect()throws IOException {}

@Override
public Object getContent()throws IOException {
返回super.getContent();

$ b @Override
public InputStream getInputStream()throws IOException {
return new ByteArrayInputStream(urlData.getBytes());
}
}

类GroovyResourceStreamHandler扩展了URLStreamHandler {

private final String scriptSource;

public GroovyResourceStreamHandler(String scriptSource){
this.scriptSource = scriptSource;

$ b @Override
protected URLConnection openConnection(URL u)抛出IOException {
GroovyResourceConnection connection = new GroovyResourceConnection(u,scriptSource);
返回连接;




code


$ b <然后你可以用下面的代码安装这个东西:

  GroovyClassLoader groovyClassLoader = new GroovyClassLoader(); 
groovyClassLoader.setResourceLoader(new CustomGroovyResourceLoader(groovyClassLoader.getResourceLoader()));


I compile single groovy source module "in fly" using GroovyClassLoader.parseClass(src) and all is ok.

But problem is when this source module imports other classes, these are not compiled yet. Traditional compiling when I start compilation of one source but other are required and ready on source path, are compiled too.

How can I use GroovyClassLoader with target to compile all other required sources NOT FROM FILESYSYSTEM. My sources are for example in database, remote http via URI etc.

解决方案

The key is to make custom URL handling -- you have to implement a URLStreamHandler and a URLConnection.

IF you google around, there's some good documentation on how to implement the stream handler and connection classes -- but for what you're doing, you really only need dummy implementations.

Here's some source code to bootstrap you -- it demonstrates how to connect the pieces up. If you provide some implementation of lookupScripCodeWithJDBCorWhatever you'll be good to go.

import groovy.lang.GroovyResourceLoader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;

public class CustomGroovyResourceLoader implements GroovyResourceLoader {

    private final GroovyResourceLoader parentLoader;

    public CustomGroovyResourceLoader(GroovyResourceLoader parentLoader) {
        this.parentLoader = parentLoader;
    }

    @Override
    public URL loadGroovySource(String filename) throws MalformedURLException {
        URL resourceURL = null;

        if (parentLoader != null) {
            resourceURL = parentLoader.loadGroovySource(filename);
        }

        if (resourceURL == null) {
            resourceURL = createURL(filename);
        }

        return resourceURL;
    }

    public URL createURL(String resourceName) throws MalformedURLException {

        String scriptSourceCode = lookupScripCodeWithJDBCorWhatever(resourceName);

        return new URL(null, "groovy:///" + resourceName,
                new GroovyResourceStreamHandler(scriptSourceCode));

    }

    private String lookupScripCodeWithJDBCorWhatever(String resourceName) {

        //TODO: blah blah blah
        return null;
    }

    class GroovyResourceConnection extends URLConnection {

        private final String urlData;

        protected GroovyResourceConnection(URL url, String logic) {
            super(url);
            this.urlData = logic;
        }

        @Override
        public void connect() throws IOException {}

        @Override
        public Object getContent() throws IOException {
            return super.getContent();
        }

        @Override
        public InputStream getInputStream() throws IOException {
            return new ByteArrayInputStream(urlData.getBytes());
        }
    }

    class GroovyResourceStreamHandler extends URLStreamHandler {

        private final String scriptSource;

        public GroovyResourceStreamHandler(String scriptSource) {
            this.scriptSource = scriptSource;
        }

        @Override
        protected URLConnection openConnection(URL u) throws IOException {
            GroovyResourceConnection connection = new GroovyResourceConnection(u, scriptSource);
            return connection;

        }
    }

}

You then install this thing with some code that looks like this:

GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
groovyClassLoader.setResourceLoader( new CustomGroovyResourceLoader( groovyClassLoader.getResourceLoader() ) );

这篇关于如何编译Groovy源文件,但不是来自文件系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆