001    package railo.runtime.tag;
002    
003    import railo.commons.lang.StringUtil;
004    import railo.runtime.Mapping;
005    import railo.runtime.MappingImpl;
006    import railo.runtime.PageContextImpl;
007    import railo.runtime.PageSource;
008    import railo.runtime.PageSourceImpl;
009    import railo.runtime.config.Config;
010    import railo.runtime.config.ConfigWeb;
011    import railo.runtime.customtag.CustomTagUtil;
012    import railo.runtime.customtag.InitFile;
013    import railo.runtime.exp.ExpressionException;
014    import railo.runtime.exp.MissingIncludeException;
015    import railo.runtime.type.KeyImpl;
016    
017    /**
018    * Invokes a custom tag for use in CFML application pages.
019    **/
020    public final class Module extends CFTag {
021    
022            /**
023             * @throws ExpressionException 
024             * @see railo.runtime.tag.CFTag#initFile()
025             */
026            public void initFile() throws MissingIncludeException, ExpressionException {
027                    ConfigWeb config = pageContext.getConfig();
028            // MUSTMUST cache like ct
029                    //String[] filenames=getFileNames(config,getAppendix());// = appendix+'.'+config.getCFMLExtension();
030            
031                Object objTemplate =attributesScope.get(KeyImpl.TEMPLATE,null);
032                Object objName =attributesScope.get(KeyImpl.NAME,null);
033                source=null;
034                if(objTemplate!=null) {
035                            attributesScope.removeEL(KeyImpl.TEMPLATE);
036                        String template=objTemplate.toString();
037    
038                if(StringUtil.startsWith(template,'/'))  {
039                    PageSource[] sources = ((PageContextImpl)pageContext).getPageSources(template);
040                    PageSource ps = MappingImpl.isOK(sources);
041                    
042                    if(ps==null)
043                                            throw new MissingIncludeException(sources[0],"could not find template ["+template+"], file ["+sources[0].getDisplayPath()+"] doesn't exist");
044                    source=new InitFile(ps,template,template.endsWith('.'+pageContext.getConfig().getCFCExtension()));
045                }
046                else {
047                    source=new InitFile(pageContext.getCurrentPageSource().getRealPage(template),template,StringUtil.endsWithIgnoreCase(template,'.'+pageContext.getConfig().getCFCExtension()));
048                    if(!MappingImpl.isOK(source.getPageSource())){
049                                            throw new MissingIncludeException(source.getPageSource(),"could not find template ["+template+"], file ["+source.getPageSource().getDisplayPath()+"] doesn't exist");
050                    }
051                }
052                    
053                //attributesScope.removeEL(TEMPLATE);
054                setAppendix(source.getPageSource());
055                }
056                else if(objName!=null) {
057                            attributesScope.removeEL(KeyImpl.NAME);
058                    String[] filenames = toRealPath(config,objName.toString());
059                    boolean exist=false;
060                    
061                    // appcontext mappings
062                    Mapping[] ctms = pageContext.getApplicationContext().getCustomTagMappings(); 
063                    if(ctms!=null) {
064                            outer:for(int f=0;f<filenames.length;f++){
065                                    for(int i=0;i<ctms.length;i++){
066                                    source=new InitFile(ctms[i].getPageSource(filenames[f]),filenames[f],filenames[f].endsWith('.'+config.getCFCExtension()));
067                                    if(MappingImpl.isOK(source.getPageSource())) {
068                                            exist=true;
069                                            break outer;
070                                    }
071                                }
072                            }
073                    }
074                    
075                    // config mappings
076                    if(!exist) {
077                            ctms = config.getCustomTagMappings();
078                            outer:for(int f=0;f<filenames.length;f++){ 
079                                for(int i=0;i<ctms.length;i++){// TODO optimieren siehe CFTag
080                                    source=new InitFile(ctms[i].getPageSource(filenames[f]),filenames[f],filenames[f].endsWith('.'+config.getCFCExtension()));
081                                    if(MappingImpl.isOK(source.getPageSource())) {
082                                            exist=true;
083                                            break outer;
084                                    }
085                                }
086                            }
087                    }
088                
089                            if(!exist)
090                                    throw new ExpressionException("custom tag ("+CustomTagUtil.getDisplayName(config, objName.toString())+") is not defined in custom tag directory ["+(ctms.length==0?"no custom tag directory defined":CustomTagUtil.toString(ctms))+"]");
091                            
092                            setAppendix(source.getPageSource());
093                }
094                else {
095                    throw new ExpressionException("you must define attribute template or name for tag module");
096                }
097                
098            }
099    
100            private void setAppendix(PageSource source) {
101                    String appendix=source.getFileName();
102            int index=appendix.lastIndexOf('.');
103            appendix=appendix.substring(0,index);
104            setAppendix(appendix);
105            }
106    
107            /**
108             * translate a dot-notation path to a realpath
109         * @param dotPath
110         * @return realpath
111             * @throws ExpressionException 
112         */
113        private static String[] toRealPath(Config config ,String dotPath) throws ExpressionException {
114            dotPath=dotPath.trim();
115            
116            while(dotPath.indexOf('.')==0) {
117                dotPath=dotPath.substring(1);
118            }
119            int len=-1;
120            while((len=dotPath.length())>0 && dotPath.lastIndexOf('.')==len-1) {
121                dotPath=dotPath.substring(0,len-2);
122            }
123            //dotPath.replace('.','/')+".cfm";
124            return CustomTagUtil.getFileNames(config, dotPath.replace('.','/'));
125        }
126    }