001    /**
002     * Implements the CFML Function expandpath
003     */
004    package railo.runtime.functions.system;
005    
006    import java.io.IOException;
007    
008    import railo.print;
009    import railo.commons.io.SystemUtil;
010    import railo.commons.io.res.Resource;
011    import railo.commons.io.res.util.ResourceUtil;
012    import railo.commons.lang.StringUtil;
013    import railo.runtime.PageContext;
014    import railo.runtime.PageContextImpl;
015    import railo.runtime.PageSource;
016    import railo.runtime.config.ConfigWeb;
017    import railo.runtime.config.ConfigWebImpl;
018    import railo.runtime.config.ConfigWebUtil;
019    import railo.runtime.exp.PageException;
020    import railo.runtime.ext.function.Function;
021    import railo.runtime.type.util.ArrayUtil;
022    
023    public final class ExpandPath implements Function {
024    
025            private static final long serialVersionUID = 6192659914120397912L;
026    
027            public static String call(PageContext pc , String realPath) throws PageException {
028                    
029                    ConfigWeb config=pc.getConfig();
030                    realPath=realPath.replace('\\','/');
031    
032            String contextPath = pc.getHttpServletRequest().getContextPath();
033            if ( !StringUtil.isEmpty( contextPath ) && realPath.startsWith( contextPath ) )
034                realPath = realPath.substring( contextPath.length() );
035    
036            Resource res;
037            
038            if(StringUtil.startsWith(realPath,'/')) {
039                    PageContextImpl pci=(PageContextImpl) pc;
040                    ConfigWebImpl cwi=(ConfigWebImpl) config;
041                    
042                    PageSource[] sources = cwi.getPageSources(pci, pc.getApplicationContext().getMappings(), realPath, 
043                                    false, pci.useSpecialMappings(), true);
044                    
045                    if(!ArrayUtil.isEmpty(sources)) {
046                            // first check for existing
047                            for(int i=0;i<sources.length;i++){
048                                    if(sources[i].exists()) {
049                                            return toReturnValue(realPath,sources[i].getResource());
050                                    }
051                            }
052                            
053                            // no expand needed
054                            if(!SystemUtil.isWindows() && !sources[0].exists()) {
055                                    res=pc.getConfig().getResource(realPath);
056                            if(res.exists()) {
057                                    return toReturnValue(realPath,res);
058                            }
059                            }
060                            for(int i=0;i<sources.length;i++){
061                                    res=sources[i].getResource();
062                                    if(res!=null) {
063                                            return toReturnValue(realPath,res);
064                                    }
065                            }
066                    }
067    
068                    // no expand needed
069                    else if(!SystemUtil.isWindows()) {
070                            res=pc.getConfig().getResource(realPath);
071                    if(res.exists()) {
072                            return toReturnValue(realPath,res);
073                    }
074                    }
075                    
076                    
077                    //Resource[] reses = cwi.getPhysicalResources(pc,pc.getApplicationContext().getMappings(),realPath,false,pci.useSpecialMappings(),true);
078                    
079            }
080            realPath=ConfigWebUtil.replacePlaceholder(realPath, config);
081            res=pc.getConfig().getResource(realPath);
082            if(res.isAbsolute()) return toReturnValue(realPath,res);
083            
084            res=ResourceUtil.getResource(pc,pc.getBasePageSource());
085            if(!res.isDirectory())res=res.getParentResource();
086            res = res.getRealResource(realPath);
087            return toReturnValue(realPath,res);
088            
089            }
090    
091        private static String toReturnValue(String realPath,Resource res) {
092            String path;
093            char pathChar='/';
094            try {
095                path=res.getCanonicalPath();
096                pathChar=ResourceUtil.FILE_SEPERATOR;
097            } catch (IOException e) {
098                path= res.getAbsolutePath();
099            }
100            boolean pathEndsWithSep=StringUtil.endsWith(path,pathChar);
101            boolean realEndsWithSep=StringUtil.endsWith(realPath,'/');
102            
103            if(realEndsWithSep) {
104                if(!pathEndsWithSep)path=path+pathChar;
105            }
106            else if(pathEndsWithSep) {
107                path=path.substring(0,path.length()-1);
108            }
109            
110            return path;
111        }
112    }