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