001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.customtag; 020 021import java.util.ArrayList; 022import java.util.Iterator; 023import java.util.List; 024 025import lucee.commons.io.res.Resource; 026import lucee.commons.io.res.util.ResourceUtil; 027import lucee.runtime.Mapping; 028import lucee.runtime.MappingImpl; 029import lucee.runtime.PageContext; 030import lucee.runtime.PageContextImpl; 031import lucee.runtime.PageSource; 032import lucee.runtime.config.Config; 033import lucee.runtime.config.ConfigImpl; 034import lucee.runtime.config.ConfigWeb; 035import lucee.runtime.exp.ExpressionException; 036import lucee.runtime.exp.PageException; 037import lucee.runtime.type.util.ListUtil; 038 039public class CustomTagUtil { 040 041 042 public static InitFile loadInitFile(PageContext pc, String name) throws PageException { 043 044 InitFile initFile = loadInitFile(pc, name, null); 045 if(initFile!=null) { 046 return initFile; 047 } 048 // EXCEPTION 049 ConfigWeb config = pc.getConfig(); 050 // message 051 StringBuilder msg=new StringBuilder("Custom tag \"").append(getDisplayName(config,name)).append("\" was not found."); 052 053 List<String> dirs = new ArrayList(); 054 055 if (config.doLocalCustomTag()) { 056 057 dirs.add(ResourceUtil.getResource(pc, pc.getCurrentPageSource()).getParent()); 058 } 059 060 Mapping[] actms = pc.getApplicationContext().getCustomTagMappings(); 061 Mapping[] cctms = config.getCustomTagMappings(); 062 063 Resource r; 064 065 if (actms != null) { 066 for (Mapping m : actms) { 067 068 r = m.getPhysical(); 069 if (r != null) 070 dirs.add(r.toString()); 071 } 072 } 073 074 if (cctms != null) { 075 for (Mapping m : cctms) { 076 077 r = m.getPhysical(); 078 if (r != null) 079 dirs.add(r.toString()); 080 } 081 } 082 083 if(!dirs.isEmpty()) { 084 085 msg.append(" Directories searched: "); 086 087 Iterator<String> it = dirs.iterator(); 088 while (it.hasNext()) { 089 090 msg.append('"').append(it.next()).append('"'); 091 if (it.hasNext()) 092 msg.append(", "); 093 } 094 } 095 096 throw new ExpressionException(msg.toString(),getDetail(config)); 097 } 098 099 public static InitFile loadInitFile(PageContext pc, String name, InitFile defaultValue) throws PageException { 100 ConfigImpl config=(ConfigImpl) pc.getConfig(); 101 String[] filenames=getFileNames(config, name); 102 boolean doCache=config.useCTPathCache(); 103 104 105 boolean doCustomTagDeepSearch = config.doCustomTagDeepSearch(); 106 PageSource ps=null; 107 InitFile initFile; 108 109 // CACHE 110 // check local 111 String localCacheName=null; 112 Mapping[] actms = pc.getApplicationContext().getCustomTagMappings(); 113 Mapping[] cctms = config.getCustomTagMappings(); 114 115 if(doCache) { 116 if(pc.getConfig().doLocalCustomTag()){ 117 localCacheName=pc.getCurrentPageSource().getDisplayPath().replace('\\', '/'); 118 localCacheName="local:"+localCacheName.substring(0,localCacheName.lastIndexOf('/')+1).concat(name); 119 initFile=config.getCTInitFile(pc, localCacheName); 120 if(initFile!=null) return initFile; 121 } 122 123 // cache application mapping 124 if(actms!=null)for(int i=0;i<actms.length;i++){ 125 initFile=config.getCTInitFile(pc,"application:"+actms[i].hashCode()+"/"+name); 126 if(initFile!=null)return initFile; 127 } 128 129 // cache config mapping 130 if(cctms!=null)for(int i=0;i<cctms.length;i++){ 131 initFile=config.getCTInitFile(pc,"config:"+cctms[i].hashCode()+"/"+name); 132 if(initFile!=null)return initFile; 133 } 134 } 135 136 // SEARCH 137 // search local 138 if(pc.getConfig().doLocalCustomTag()){ 139 for(int i=0;i<filenames.length;i++){ 140 PageSource[] arr = ((PageContextImpl)pc).getRelativePageSources(filenames[i]); 141 //ps=pc.getRelativePageSource(filenames[i]); 142 ps=MappingImpl.isOK(arr); 143 if(ps !=null) { 144 initFile= new InitFile(ps,filenames[i],filenames[i].endsWith('.'+config.getCFCExtension())); 145 if(doCache)config.putCTInitFile(localCacheName, initFile); 146 return initFile; 147 } 148 } 149 } 150 151 // search application custom tag mapping 152 if(actms!=null){ 153 for(int i=0;i<filenames.length;i++){ 154 ps=getMapping(actms, filenames[i],doCustomTagDeepSearch); 155 if(ps!=null) { 156 initFile=new InitFile(ps,filenames[i],filenames[i].endsWith('.'+config.getCFCExtension())); 157 if(doCache)config.putCTInitFile("application:"+ps.getMapping().hashCode()+"/"+name, initFile); 158 return initFile; 159 } 160 } 161 } 162 163 // search custom tag mappings 164 for(int i=0;i<filenames.length;i++){ 165 ps=getMapping(cctms, filenames[i], doCustomTagDeepSearch); 166 if(ps!=null) { 167 initFile=new InitFile(ps,filenames[i],filenames[i].endsWith('.'+config.getCFCExtension())); 168 if(doCache)config.putCTInitFile("config:"+ps.getMapping().hashCode()+"/"+name, initFile); 169 return initFile; 170 } 171 } 172 173 return defaultValue; 174 } 175 176 177 public static String[] getFileNames(Config config, String name) throws ExpressionException { 178 String[] extensions=config.getCustomTagExtensions(); 179 if(extensions.length==0) throw new ExpressionException("Custom Tags are disabled"); 180 String[] fileNames=new String[extensions.length]; 181 182 for(int i =0;i<fileNames.length;i++){ 183 fileNames[i]=name+'.'+extensions[i]; 184 } 185 return fileNames; 186 } 187 188 private static PageSource getMapping(Mapping[] ctms, String filename, boolean doCustomTagDeepSearch) { 189 PageSource ps; 190 for(int i=0;i<ctms.length;i++){ 191 ps = ((MappingImpl) ctms[i]).getCustomTagPath(filename, doCustomTagDeepSearch); 192 if(ps!=null) return ps; 193 } 194 return null; 195 } 196 197 public static String getDisplayName(Config config,String name) { 198 String[] extensions=config.getCustomTagExtensions(); 199 if(extensions.length==0) return name; 200 201 return name+".["+ListUtil.arrayToList(extensions, "|")+"]"; 202 } 203 204 public static String getDetail(Config config) { 205 boolean hasCFC=false,hasCFML=false; 206 207 String[] extensions=config.getCustomTagExtensions(); 208 for(int i =0;i<extensions.length;i++){ 209 if(extensions[i].equalsIgnoreCase(config.getCFCExtension())) hasCFC=true; 210 else hasCFML=true; 211 } 212 StringBuilder sb=new StringBuilder(); 213 if(!hasCFC)sb.append("Component based Custom Tags are not enabled;"); 214 if(!hasCFML)sb.append("CFML based Custom Tags are not enabled;"); 215 return sb.toString(); 216 } 217 218 public static String toString(Mapping[] ctms) { 219 if(ctms==null) return ""; 220 StringBuilder sb=new StringBuilder(); 221 Resource p; 222 for(int i=0;i<ctms.length;i++){ 223 if(sb.length()!=0)sb.append(", "); 224 p = ctms[i].getPhysical(); 225 if(p!=null) 226 sb.append(p.toString()); 227 } 228 return sb.toString(); 229 } 230} 231 232