001 package railo.transformer.cfml.evaluator.impl; 002 003 import java.io.ByteArrayInputStream; 004 import java.io.ByteArrayOutputStream; 005 import java.io.IOException; 006 import java.util.zip.ZipEntry; 007 import java.util.zip.ZipInputStream; 008 009 import railo.commons.io.IOUtil; 010 import railo.commons.io.res.Resource; 011 import railo.commons.io.res.util.ResourceUtil; 012 import railo.commons.lang.Md5; 013 import railo.commons.lang.StringUtil; 014 import railo.commons.lang.SystemOut; 015 import railo.loader.util.Util; 016 import railo.runtime.PageSource; 017 import railo.runtime.config.Config; 018 import railo.runtime.config.ConfigImpl; 019 import railo.runtime.config.ConfigWebUtil; 020 import railo.runtime.exp.TemplateException; 021 import railo.transformer.bytecode.statement.tag.Attribute; 022 import railo.transformer.bytecode.statement.tag.Tag; 023 import railo.transformer.bytecode.statement.tag.TagImport; 024 import railo.transformer.bytecode.util.ASMUtil; 025 import railo.transformer.cfml.evaluator.EvaluatorException; 026 import railo.transformer.cfml.evaluator.EvaluatorSupport; 027 import railo.transformer.library.function.FunctionLib; 028 import railo.transformer.library.tag.CustomTagLib; 029 import railo.transformer.library.tag.TagLib; 030 import railo.transformer.library.tag.TagLibException; 031 import railo.transformer.library.tag.TagLibFactory; 032 import railo.transformer.library.tag.TagLibTag; 033 import railo.transformer.util.CFMLString; 034 035 036 /** 037 * 038 */ 039 public final class Import extends EvaluatorSupport { 040 041 public void evaluate(Tag tag,TagLibTag libTag) throws EvaluatorException { 042 } 043 044 045 //� 046 /** 047 * @see railo.transformer.cfml.evaluator.Evaluator#execute(railo.runtime.config.Config, org.w3c.dom.Element, railo.transformer.library.tag.TagLibTag, railo.transformer.library.function.FunctionLib[], railo.transformer.util.CFMLString) 048 */ 049 public TagLib execute(Config config,Tag tag, TagLibTag libTag, FunctionLib[] flibs,CFMLString cfml) throws TemplateException { 050 TagImport ti=(TagImport) tag; 051 Attribute p = tag.getAttribute("prefix"); 052 Attribute t = tag.getAttribute("taglib"); 053 Attribute path = tag.getAttribute("path"); 054 055 if(p!=null || t!=null){ 056 if(p==null) 057 throw new TemplateException(cfml,"Wrong Context, missing attribute [prefix] for tag "+tag.getFullname()); 058 if(t==null) 059 throw new TemplateException(cfml,"Wrong Context, missing attribute [taglib] for tag "+tag.getFullname()); 060 061 if(path!=null) 062 throw new TemplateException(cfml,"Wrong context, you have an invalid attributes constellation for the tag "+tag.getFullname()+", " + 063 "you cannot mix attribute [path] with attributes [taglib] and [prefix]"); 064 065 return executePT(config, tag, libTag, flibs, cfml); 066 } 067 if(path==null) throw new TemplateException(cfml,"Wrong context, you have an invalid attributes constellation for the tag "+tag.getFullname()+", " + 068 "you need to define the attributes [prefix] and [taglib], the attribute [path] or simply define a attribute value"); 069 070 String strPath=ASMUtil.getAttributeString(tag,"path",null); 071 if(strPath==null) throw new TemplateException(cfml,"attribute [path] must be a constant value"); 072 ti.setPath(strPath); 073 074 return null; 075 076 } 077 078 private TagLib executePT(Config config,Tag tag, TagLibTag libTag, FunctionLib[] flibs,CFMLString cfml) throws TemplateException { 079 080 // Attribute prefix 081 String nameSpace=ASMUtil.getAttributeString(tag,"prefix",null); 082 if(nameSpace==null) throw new TemplateException(cfml,"attribute [prefix] must be a constant value"); 083 nameSpace=nameSpace.trim(); 084 String nameSpaceSeparator=StringUtil.isEmpty(nameSpace)?"":":"; 085 086 087 // Attribute taglib 088 String textTagLib=ASMUtil.getAttributeString(tag,"taglib",null); 089 if(textTagLib==null) throw new TemplateException(cfml,"attribute [taglib] must be a constant value"); 090 091 textTagLib=textTagLib.replace('\\','/'); 092 textTagLib=ConfigWebUtil.replacePlaceholder(textTagLib, config); 093 // File TagLib 094 String ext=ResourceUtil.getExtension(textTagLib,null); 095 boolean hasTldExtension="tld".equalsIgnoreCase(ext); 096 097 Resource absFile=config.getResource(textTagLib); 098 // TLD 099 if(absFile.isFile()) return _executeTLD(config,absFile,nameSpace,nameSpaceSeparator,cfml); 100 // CTD 101 //else if(absFile.isDirectory()) return _executeCTD(absFile,textPrefix); 102 103 104 // Second Change 105 if(textTagLib.startsWith("/")){ 106 //config.getPhysical(textTagLib); 107 PageSource ps = ((ConfigImpl)config).getPageSourceExisting(null,null,textTagLib,false,false,true,false); 108 109 //config.getConfigDir() 110 if(ps!=null) { 111 if(ps.physcalExists()) { 112 Resource file = ps.getPhyscalFile(); 113 // TLD 114 if(file.isFile()) return _executeTLD(config,file,nameSpace,nameSpaceSeparator,cfml); 115 } 116 // CTD 117 if(!hasTldExtension)return _executeCTD(textTagLib,nameSpace,nameSpaceSeparator); 118 } 119 } 120 else { 121 Resource sourceFile=cfml.getSourceFile().getPhyscalFile(); 122 if(sourceFile!=null) { 123 Resource file = sourceFile.getParentResource().getRealResource(textTagLib); 124 // TLD 125 if(file.isFile()) return _executeTLD(config,file,nameSpace,nameSpaceSeparator,cfml); 126 // CTD 127 if(!hasTldExtension)return _executeCTD(textTagLib,nameSpace,nameSpaceSeparator); 128 } 129 } 130 throw new TemplateException(cfml,"invalid definition of the attribute taglib ["+textTagLib+"]"); 131 } 132 133 /** 134 * @param fileTagLib 135 * @return 136 * @throws EvaluatorException 137 */ 138 private TagLib _executeTLD(Config config, Resource fileTagLib,String nameSpace,String nameSpaceSeparator, CFMLString cfml) throws TemplateException { 139 // change extesnion 140 String ext=ResourceUtil.getExtension(fileTagLib,null); 141 if("jar".equalsIgnoreCase(ext)) { 142 // check anchestor file 143 Resource newFileTagLib = ResourceUtil.changeExtension(fileTagLib,"tld"); 144 if(newFileTagLib.exists())fileTagLib=newFileTagLib; 145 // check inside jar 146 else { 147 Resource tmp = getTLDFromJarAsFile(config,fileTagLib); 148 if(tmp!=null)fileTagLib=tmp; 149 } 150 } 151 152 try { 153 154 TagLib taglib = TagLibFactory.loadFromFile(fileTagLib); 155 taglib.setNameSpace(nameSpace); 156 taglib.setNameSpaceSeperator(nameSpaceSeparator); 157 return taglib; 158 } 159 catch (TagLibException e) { 160 161 throw new TemplateException(cfml,e.getMessage()); 162 } 163 } 164 165 private Resource getTLDFromJarAsFile(Config config, Resource jarFile) { 166 Resource jspTagLibDir = config.getTempDirectory().getRealResource("jsp-taglib"); 167 if(!jspTagLibDir.exists())jspTagLibDir.mkdirs(); 168 169 String filename=null; 170 try { 171 filename=Md5.getDigestAsString(ResourceUtil.getCanonicalPathEL(jarFile)+jarFile.lastModified()); 172 } catch (IOException e) {} 173 174 Resource tldFile = jspTagLibDir.getRealResource(filename+".tld"); 175 if(tldFile.exists() ) return tldFile; 176 177 178 byte[] barr = getTLDFromJarAsBarr(config,jarFile); 179 if(barr==null)return null; 180 181 try { 182 IOUtil.copy(new ByteArrayInputStream(barr), tldFile,true); 183 } 184 catch (IOException e) {} 185 return tldFile; 186 } 187 188 189 private byte[] getTLDFromJarAsBarr(Config c,Resource jarFile) { 190 ZipInputStream zis = null; 191 try { 192 zis = new ZipInputStream(IOUtil.toBufferedInputStream(jarFile.getInputStream())); 193 194 byte[] buffer = new byte[0xffff]; 195 int bytes_read; 196 197 ZipEntry ze; 198 byte[] barr; 199 while((ze = zis.getNextEntry()) != null) { 200 if (!ze.isDirectory() && StringUtil.endsWithIgnoreCase(ze.getName(),".tld")) { 201 SystemOut.printDate(c.getOutWriter(),"found tld in file ["+jarFile+"] at position "+ze.getName()); 202 ByteArrayOutputStream baos=new ByteArrayOutputStream(); 203 while((bytes_read = zis.read(buffer)) != -1) 204 baos.write(buffer, 0, bytes_read); 205 //String name = ze.getName().replace('\\', '/'); 206 barr=baos.toByteArray(); 207 zis.closeEntry(); 208 baos.close(); 209 return barr; 210 } 211 } 212 } 213 catch (IOException ioe) {} 214 finally { 215 Util.closeEL(zis); 216 } 217 return null; 218 } 219 220 221 /** 222 * @param textTagLib 223 * @param nameSpace 224 * @return 225 */ 226 private TagLib _executeCTD(String textTagLib, String nameSpace, String nameSpaceSeparator) { 227 return new CustomTagLib(textTagLib,nameSpace,nameSpaceSeparator); 228 } 229 230 }