001package gu.sql2java.generator;
002
003import java.io.ByteArrayInputStream;
004import java.io.FileNotFoundException;
005import java.io.IOException;
006import java.io.InputStream;
007import java.util.ArrayList;
008import java.util.List;
009import java.util.Vector;
010
011import org.apache.commons.collections.ExtendedProperties;
012import org.apache.velocity.exception.ResourceNotFoundException;
013import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
014import org.apache.velocity.util.StringUtils;
015
016import com.google.common.base.Function;
017import com.google.common.base.Joiner;
018import com.google.common.base.Strings;
019import com.google.common.collect.Lists;
020
021import net.gdface.utils.ClassResourceUtils;
022import net.gdface.utils.ClassResourceUtils.TypeFilter;
023
024import static com.google.common.base.Preconditions.*;
025
026/**
027 * 基于 {@link ClasspathResourceLoader}的classpath资源加载器<br>
028 * 
029 * 支持多路径搜索的 ResourceLoader 实现<br>
030 * 对于非'/'开始的资源名,自动添加预设的前缀(prefix)搜索
031 * 
032 * @author guyadong
033 *
034 */
035public class Sql2javaClasspathResourceLoader extends ClasspathResourceLoader {
036    /**
037     * The paths to search for templates.
038     */
039    private List<String> prefix = new ArrayList<>();
040        public Sql2javaClasspathResourceLoader() {
041        }
042
043        @SuppressWarnings("unchecked")
044        @Override
045        public void init(ExtendedProperties configuration) {
046                Vector<String> vector=configuration.getVector("prefix");
047        prefix.addAll( Lists.transform(vector, new Function<String,String>(){
048
049                        @Override
050                        public String apply(final String input) {
051                                String path = StringUtils.normalizePath(input);
052                                checkArgument(!Strings.isNullOrEmpty(path),"INVALID resource path prefix [%s]",input);
053                                if (path.equals("/")){
054                                        return path;
055                                }
056                                // 删除末尾的'/'
057                                return path.endsWith("/") ? path.substring(0, path.length()-1) : path;
058                        }}) );
059        if (log.isTraceEnabled())
060        {
061            log.trace("Sql2javaClasspathResourceLoader : prefix:" + prefix.toString());
062        }
063                super.init(configuration);
064        }
065
066        @Override
067        public InputStream getResourceStream(final String name) throws ResourceNotFoundException {
068        if (Strings.isNullOrEmpty(name))
069        {
070            throw new ResourceNotFoundException ("No template name provided");
071        }
072                String path = StringUtils.normalizePath(name);
073                if (Strings.isNullOrEmpty(path))
074        {
075            String msg = "No valid template name provided " + name +
076                " contains .. and may be trying to access invalid reference";
077
078            log.error("Sql2javaClasspathResourceLoader : " + msg);
079
080            throw new ResourceNotFoundException ( msg );
081        }
082
083                if(name.startsWith("/")){
084                        return toResourceStream(path);
085                }
086                for(String p:prefix){
087                        try {
088                                return toResourceStream(p + path);
089                        } catch (ResourceNotFoundException e) {
090                                // CONTINUE
091                        }
092                }
093        throw new ResourceNotFoundException( "Sql2javaClasspathResourceLoader Error: cannot find resource " + name );
094        }
095        private  InputStream toResourceStream(final String path) {
096                try {
097                        // 尝试将path作为文件夹读取文件夹中的文件列表
098                        List<String> fileList = ClassResourceUtils.getResourceList(getClass(), path,TypeFilter.DEFAULT);
099                        return new ByteArrayInputStream(Joiner.on("\n").join(fileList).getBytes());
100                } catch (FileNotFoundException e) {
101                        // 尝试将path 作为普通文件路径读取
102                        return super.getResourceStream(path);
103                } catch (IOException e) {
104                        throw new RuntimeException(e);
105                }
106        }
107}