cmsjsploader.java

来自「java 编写的程序」· Java 代码 · 共 441 行 · 第 1/2 页

JAVA
441
字号
                    res.getOutputStream().flush();
                }
            } catch (IllegalStateException e) {
                // Uncritical, might happen if JSP error page was used
                if (DEBUG > 1) System.err.println("JspLoader.load() ignoring IllegalStateException " + e);
            } catch (java.net.SocketException e) {        
                // Uncritical, might happen if client (browser) does not wait until end of page delivery
                if (DEBUG > 1) System.err.println("JspLoader.load() ignoring SocketException " + e);
            } catch (Exception e) {
                System.err.println("Error in CmsJspLoader.load() while writing buffer to final stream: " + e.toString());
                System.err.println(com.opencms.util.Utils.getStackTrace(e));
                throw new CmsException("Error in CmsJspLoader.load() while writing buffer to final stream for " + file.getAbsolutePath() + "\n" + e, CmsException.C_LAUNCH_ERROR, e);
            }        
        }
        
        if (DEBUG > 0) {
            long timer2 = System.currentTimeMillis() - timer1;
            System.err.println("========== JspLoader time delivering JSP for " + file.getAbsolutePath() + ": " + timer2 + "ms");
        }        
    }

    /**
     * Returns the JSP file name for a OpenCms VFS resource.
     * The name give must be a absolute URI in the OpenCms VFS,
     * e.g. CmsFile.getAbsolutePath()
     *
     * @param name The file to calculate the JSP name for
     * @return The JSP name for the file
     */    
    public static String getJspName(String name) {
        return name.replace('\\', 'T').replace('/', 'T') + '.' + name.hashCode() + C_JSP_EXTENSION;
    }
    
    /**
     * Returns the uri for a given JSP, i.e. the path in the file
     * system relative to the web application directory /WEB-INF/
     *
     * @param name The name of the JSP file 
     * @param online Flag to check if this is request is online or not
     * @return The full uri to the JSP
     */
    public static String getJspUri(String name, boolean online) {
        return "/WEB-INF/jsp/" + (online?"online/":"offline/") + getJspName(name);  
    }
    
    /**
     * Returns the path for a given JSP 
     *
     * @param name The name of the JSP file 
     * @param online Flag to check if this is request is online or not
     * @return The full path to the JSP
     */
    public static String getJspPath(String name, boolean online) {
        return m_jspRepository + File.separator + (online?"online":"offline") + File.separator + name;
    }
    
    /**
     * Updates a JSP page in the real file system in case the VFS resource has changed.
     * Also processes the <cms:jspfilename> tags before the JSP is written to the real FS.
     * Also recursivly updates all files that are referenced by a <cms:jspfilename> tag 
     * on this page to make sure the file actually exists in the real FS.
     */
    private synchronized String updateJsp(CmsObject cms, CmsResource file, CmsFlexRequest req, Set updates) throws CmsException {
        
        String jspTargetName = getJspName(file.getAbsolutePath());
        String jspPath = getJspPath(jspTargetName, req.isOnline());
        
        File d = new File(jspPath).getParentFile();
        if (! (d != null) && (d.exists() && d.isDirectory() && d.canRead())) {
            log("Could not access directory for " + jspPath);
            throw new CmsException("JspLoader: Could not access directory for " + jspPath);
        }    
        
        if (updates.contains(jspTargetName)) return null;
        updates.add(jspTargetName);
        
        boolean mustUpdate = false;
        
        File f = new File(jspPath);        
        if (!f.exists()) {
            // File does not exist in FS
            mustUpdate = true;
        } else if (f.lastModified() <= file.getDateLastModified()) {
            // File in FS is older then file in VFS
            mustUpdate = true;
        }                
        
        String jspfilename = "/WEB-INF/jsp/" + (req.isOnline()?"online/":"offline/") + f.getName();               
        
        if (mustUpdate) {
            if (DEBUG > 2) System.err.println("JspLoader writing new file: " + jspfilename);            
            byte[] contents = req.getCmsObject().readFile(file.getAbsolutePath()).getContents();
            
            try {
                FileOutputStream fs = new FileOutputStream(f);                
                String page = new String(contents);
                StringBuffer buf = new StringBuffer(contents.length);
                
                String NAME_START = "<%@";
                String NAME_END ="%>";

                int p0 = 0, i2 = 0, slen = NAME_START.length(), elen = NAME_END.length();
                // Check if any jsp name references occur in the file
                int i1 = page.indexOf(NAME_START);
                while (i1 >= 0) {
                    // Parse the file and replace jsp name references 
                    i2 = page.indexOf(NAME_END, i1 + slen);
                    if (i2 > i1) {
                        String directive = page.substring(i1 + slen, i2);
                        if (DEBUG > 2) System.err.println("JspLoader: Detected " + NAME_START + directive + NAME_END);

                        int t1=0, t2=0, t3=0, t4=0, t5=0, t6=slen, t7=0;
                        while (directive.charAt(t1) == ' ') t1++;
                        String filename = null;                        
                        if (directive.startsWith("include", t1)) {            
                            if (DEBUG > 2) System.err.println("JspLoader: Detected 'include' directive!");                            
                            t2 = directive.indexOf("file", t1 + 7);
                            t5 = 6;
                        } else if (directive.startsWith("page", t1)) {
                            if (DEBUG > 2) System.err.println("JspLoader: Detected 'page' directive!");                            
                            t2 = directive.indexOf("errorPage", t1 + 4);
                            t5 = 11;
                        } else if (directive.startsWith("cms", t1)) {
                            if (DEBUG > 2) System.err.println("JspLoader: Detected 'cms' directive!");                            
                            t2 = directive.indexOf("file", t1 + 3);
                            t5 = 4; t6 = 0; t7 = elen; 
                        }
                        
                        if (t2 > 0) {
                            String sub = directive.substring(t2 + t5); 
                            char c1 = sub.charAt(t3);
                            while ((c1 == ' ') || (c1 == '=') || (c1 == '"')) c1 = sub.charAt(++t3);
                            t4 = t3;
                            while (c1 != '"') c1 = sub.charAt(++t4);
                            if (t4 > t3) filename=sub.substring(t3,t4);
                            if (DEBUG > 2) System.err.println("JspLoader: File given in directive is: " + filename);                            
                        }
                        
                        if (filename != null) {
                            // a file was found, changes have to be made
                            String pre = ((t7 == 0)?directive.substring(0,t2+t3+t5):"");                            ;
                            String suf = ((t7 == 0)?directive.substring(t2+t3+t5+filename.length()):"");
                            // Now try to update the referenced file 
                            String absolute = req.toAbsolute(filename);
                            if (DEBUG > 2) System.err.println("JspLoader: Absolute location=" + absolute);
                            String jspname = null;
                            try {
                                // Make sure the jsp referenced file is generated
                                CmsResource jsp = cms.readFileHeader(absolute);
                                updateJsp(cms, jsp, req, updates);
                                jspname = getJspUri(jsp.getAbsolutePath(), req.isOnline());
                            } catch (Exception e) {
                                jspname = null;
                                if (DEBUG > 2) System.err.println("JspLoader: Error while creating jsp file " + absolute + "\n" + e);
                            }
                            if (jspname != null) {
                                // Only change something in case no error had occured
                                if (DEBUG > 2) System.err.println("JspLoader: Name of jsp file is " + jspname);
                                directive = pre + jspname + suf;
                                if (DEBUG > 2) System.err.println("JspLoader: Changed directive to " + NAME_START + directive + NAME_END);                                                     
                            }
                        }
                        
                        buf.append(page.substring(p0, i1 + t6));
                        buf.append(directive);
                        p0 = i2 + t7;
                        i1 = page.indexOf(NAME_START, p0);
                    }
                }
                if (i2 > 0) {
                    buf.append(page.substring(p0, page.length()));
                    contents = buf.toString().getBytes();
                }
                                
                fs.write(contents);                
                fs.close();
                
                log("Updated JSP file \"" + jspfilename + "\" for resource \"" + file.getAbsolutePath() + "\"") ;
            } catch (Exception e) {
                throw new CmsException("JspLauncher: Could not write to file '" + f.getName() + "'\n" + e, e);
            }
        }              
        
        return jspfilename;
    }
    
    
    /**
     * Does the job of including the JSP.
     * This should be called from a CmsFlexRequestDispatcher only.
     */
    public void service(CmsObject cms, CmsResource file, CmsFlexRequest req, CmsFlexResponse res)
    throws CmsException {
        
        String target = updateJsp(cms, file, req, new HashSet(11));
        
        try {              
            // Important: Indicate that all output must be buffered
            res.setOnlyBuffering(true);   
            // Dispatch to external file
            req.getCmsRequestDispatcher(file.getAbsolutePath(), target).include(req, res);  
        } catch (Exception e) {
            System.err.println("Error in CmsJspLoader.doService(): " + e.toString());
            System.err.println(com.opencms.util.Utils.getStackTrace(e));
            throw new CmsException("Error in CmsJspLoader.doServive():\n" + e, CmsException.C_FLEX_LOADER, e);            
        }
    }
    
    /**     
     * Logs a message to the OpenCms log in the channel "flex_loader".
     *
     * @param message The string to write in the log file
     */        
    private void log(String message) {
        if (com.opencms.boot.I_CmsLogChannels.C_PREPROCESSOR_IS_LOGGING) {
            com.opencms.boot.CmsBase.log(com.opencms.boot.CmsBase.C_FLEX_LOADER, "[CmsJspLoader] " + message);
        }
    }    
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?