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}