001    package railo.runtime.customtag;
002    
003    import railo.commons.io.res.Resource;
004    import railo.commons.io.res.util.ResourceUtil;
005    import railo.runtime.Mapping;
006    import railo.runtime.MappingImpl;
007    import railo.runtime.PageContext;
008    import railo.runtime.PageContextImpl;
009    import railo.runtime.PageSource;
010    import railo.runtime.config.Config;
011    import railo.runtime.config.ConfigImpl;
012    import railo.runtime.config.ConfigWeb;
013    import railo.runtime.exp.ExpressionException;
014    import railo.runtime.exp.PageException;
015    import railo.runtime.type.util.ArrayUtil;
016    import railo.runtime.type.util.ListUtil;
017    
018    public class CustomTagUtil {
019            
020    
021    
022    
023            public static InitFile loadInitFile(PageContext pc, String name) throws PageException  {
024                    InitFile initFile = loadInitFile(pc, name, null);
025                    if(initFile!=null) {
026                    return initFile;
027            }
028             // EXCEPTION
029            ConfigWeb config = pc.getConfig();
030            // message
031            StringBuffer msg=new StringBuffer("custom tag \"");
032            msg.append(getDisplayName(config,name));
033            msg.append("\" is not defined in directory \"");
034            msg.append(ResourceUtil.getResource(pc, pc.getCurrentPageSource()).getParent());
035            msg.append('"');
036            
037            Mapping[] actms = pc.getApplicationContext().getCustomTagMappings();
038            Mapping[] cctms = config.getCustomTagMappings();
039            int asize=ArrayUtil.size(actms);
040            int csize=ArrayUtil.size(cctms);
041            int size=asize+csize;
042            
043            if(size>0){
044                    if(size==1)msg.append(" and directory ");
045                    else msg.append(" and directories ");
046                    msg.append("\"");
047                    
048                    String list;
049                    if(asize>0) {
050                            list=toString(actms);
051                            if(csize>0) list+=", "+toString(cctms);
052                    }
053                    else {
054                            list=toString(cctms);
055                    }
056                    
057                    
058                    msg.append(list);
059                    msg.append("\"");
060            }
061            throw new ExpressionException(msg.toString(),getDetail(config));
062            
063            }
064            
065            public static InitFile loadInitFile(PageContext pc, String name, InitFile defaultValue) throws PageException  {
066            ConfigImpl config=(ConfigImpl) pc.getConfig();
067            String[] filenames=getFileNames(config, name);
068            boolean doCache=config.useCTPathCache();
069            
070            
071            boolean doCustomTagDeepSearch = config.doCustomTagDeepSearch();
072            PageSource ps=null;
073            InitFile initFile;
074        
075       // CACHE
076            // check local
077            String localCacheName=null;    
078            Mapping[] actms = pc.getApplicationContext().getCustomTagMappings();
079            Mapping[] cctms = config.getCustomTagMappings();
080            
081            if(doCache) {
082                    if(pc.getConfig().doLocalCustomTag()){
083                            localCacheName=pc.getCurrentPageSource().getDisplayPath().replace('\\', '/');
084                            localCacheName="local:"+localCacheName.substring(0,localCacheName.lastIndexOf('/')+1).concat(name);
085                            initFile=config.getCTInitFile(pc, localCacheName);
086                            if(initFile!=null) return initFile;
087                    }
088                    
089                    // cache application mapping
090                    if(actms!=null)for(int i=0;i<actms.length;i++){
091                            initFile=config.getCTInitFile(pc,"application:"+actms[i].hashCode()+"/"+name);
092                            if(initFile!=null)return initFile;
093                    }
094                    
095                    // cache config mapping
096                    if(cctms!=null)for(int i=0;i<cctms.length;i++){
097                            initFile=config.getCTInitFile(pc,"config:"+cctms[i].hashCode()+"/"+name);
098                            if(initFile!=null)return initFile;
099                    }
100            }
101            
102         // SEARCH
103            // search local
104            if(pc.getConfig().doLocalCustomTag()){
105                        for(int i=0;i<filenames.length;i++){
106                        PageSource[] arr = ((PageContextImpl)pc).getRelativePageSources(filenames[i]);
107                            //ps=pc.getRelativePageSource(filenames[i]);
108                        ps=MappingImpl.isOK(arr);
109                                    if(ps !=null) {
110                                            initFile= new InitFile(ps,filenames[i],filenames[i].endsWith('.'+config.getCFCExtension()));
111                                            if(doCache)config.putCTInitFile(localCacheName, initFile);
112                                    return initFile;
113                                    }
114                    }
115            }
116            
117            // search application custom tag mapping
118            if(actms!=null){
119                    for(int i=0;i<filenames.length;i++){
120                    ps=getMapping(actms, filenames[i],doCustomTagDeepSearch);
121                    if(ps!=null) {
122                            initFile=new InitFile(ps,filenames[i],filenames[i].endsWith('.'+config.getCFCExtension()));
123                            if(doCache)config.putCTInitFile("application:"+ps.getMapping().hashCode()+"/"+name, initFile);
124                            return initFile;
125                    }
126                }
127            }
128            
129            // search custom tag mappings
130            for(int i=0;i<filenames.length;i++){
131                    ps=getMapping(cctms, filenames[i], doCustomTagDeepSearch);
132                    if(ps!=null) {
133                            initFile=new InitFile(ps,filenames[i],filenames[i].endsWith('.'+config.getCFCExtension()));
134                            if(doCache)config.putCTInitFile("config:"+ps.getMapping().hashCode()+"/"+name, initFile);
135                            return initFile;
136                    }
137            }
138            
139            return defaultValue;
140            }
141            
142            
143            public static String[] getFileNames(Config config, String name) throws ExpressionException {
144                    String[] extensions=config.getCustomTagExtensions();
145            if(extensions.length==0) throw new ExpressionException("Custom Tags are disabled");
146            String[] fileNames=new String[extensions.length];
147                    
148            for(int i =0;i<fileNames.length;i++){
149                    fileNames[i]=name+'.'+extensions[i];
150            }
151            return fileNames;
152            }
153            
154             private static PageSource getMapping(Mapping[] ctms, String filename, boolean doCustomTagDeepSearch) {
155                    PageSource ps;
156                    for(int i=0;i<ctms.length;i++){
157                            ps = ((MappingImpl) ctms[i]).getCustomTagPath(filename, doCustomTagDeepSearch);
158                                    if(ps!=null) return ps;
159                    }
160                            return null;
161                    }
162             
163             public static  String getDisplayName(Config config,String name) {
164                    String[] extensions=config.getCustomTagExtensions();
165            if(extensions.length==0) return name;
166            
167                    return name+".["+ListUtil.arrayToList(extensions, "|")+"]";
168            }
169             
170             public static String getDetail(Config config) {
171            boolean hasCFC=false,hasCFML=false;
172            
173            String[] extensions=config.getCustomTagExtensions();
174            for(int i =0;i<extensions.length;i++){
175                    if(extensions[i].equalsIgnoreCase(config.getCFCExtension())) hasCFC=true;
176                    else hasCFML=true;
177            }
178            StringBuffer sb=new StringBuffer();
179            if(!hasCFC)sb.append("Component based Custom Tags are not enabled;");
180            if(!hasCFML)sb.append("CFML based Custom Tags are not enabled;");
181            return sb.toString();
182            }
183             
184             public static String toString(Mapping[] ctms) {
185                    if(ctms==null) return "";
186            StringBuffer sb=new StringBuffer();
187            Resource p;
188            for(int i=0;i<ctms.length;i++){
189                    if(sb.length()!=0)sb.append(", ");
190                    p = ctms[i].getPhysical();
191                    if(p!=null)
192                            sb.append(p.toString());
193            }
194            return sb.toString();
195            }
196    }
197    
198