📄 cmsjsploader.java
字号:
* Returns the absolute path in the "real" file system 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 + (online?"online":"offline") + name;
}
/**
* Returns the absolute path in the "real" file system for the JSP repository
* toplevel directory.
*
* @return The full path to the JSP repository
*/
public static String getJspRepository() {
return m_jspRepository;
}
/**
* Updates a JSP page in the "real" file system in case the VFS resource has changed.<p>
*
* Also processes the <code><%@ cms %></code> tags before the JSP is written to the real FS.
* Also recursivly updates all files that are referenced by a <code><%@ cms %></code> tag
* on this page to make sure the file actually exists in the real FS.
* All <code><%@ include %></code> tags are parsed and the name in the tag is translated
* from the OpenCms VFS path to the path in the real FS.
* The same is done for filenames in <code><%@ page errorPage=... %></code> tags.
*
* @param cms Used to access the OpenCms VFS
* @param file The reqested JSP file resource in the VFS
* @param req The current request
* @param res The current response
* @param updates A Set containing all JSP pages that have been already updated
*
* @return The file name of the updated JSP in the "real" FS
*
* @throws ServletException might be thrown in the process of including the JSP
* @throws IOException might be thrown in the process of including the JSP
*/
private synchronized String updateJsp(CmsObject cms, CmsResource file, ServletRequest req, CmsFlexController controller, Set updates)
throws IOException, ServletException {
String jspTargetName = getJspName(file.getAbsolutePath());
// check for inclusion loops
if (updates.contains(jspTargetName)) return null;
updates.add(jspTargetName);
String jspPath = getJspPath(jspTargetName, controller.getCurrentRequest().isOnline());
File d = new File(jspPath).getParentFile();
if ((d == null) || (d.exists() && ! (d.isDirectory() && d.canRead()))) {
if (I_CmsLogChannels.C_LOGGING && A_OpenCms.isLogging(I_CmsLogChannels.C_OPENCMS_CRITICAL))
A_OpenCms.log(I_CmsLogChannels.C_OPENCMS_CRITICAL, "Could not access directory for " + jspPath);
throw new ServletException("JspLoader: Could not access directory for " + jspPath);
}
if (! d.exists()) {
// create directory structure
d.mkdirs();
}
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;
} else if (controller.getCurrentRequest().isDoRecompile()) {
// Recompile is forced with parameter
mustUpdate = true;
}
String jspfilename = getJspUri(file.getAbsolutePath(), controller.getCurrentRequest().isOnline());
if (mustUpdate) {
if (DEBUG > 2) System.err.println("JspLoader writing new file: " + jspfilename);
byte[] contents = null;
String jspEncoding = null;
try {
contents = cms.readFile(file.getAbsolutePath()).getContents();
// Encoding project:
// Check the JSP "content-encoding" property
jspEncoding = cms.readProperty(file.getAbsolutePath(), I_CmsConstants.C_PROPERTY_CONTENT_ENCODING, false);
if (jspEncoding == null) jspEncoding = C_DEFAULT_JSP_ENCODING;
jspEncoding = jspEncoding.trim().toUpperCase();
} catch (CmsException e) {
throw new ServletException("JspLoader: Could not read contents for file '" + file.getAbsolutePath() + "'", e);
}
try {
FileOutputStream fs = new FileOutputStream(f);
// Encoding project:
// We need to use some encoding to convert bytes to String
// corectly. Internally a JSP will always be stored in the
// system default encoding since they are just a variation of
// the "plain" resource type.
String page = new String(contents, A_OpenCms.getDefaultEncoding());
StringBuffer buf = new StringBuffer(contents.length);
int p0 = 0, i2 = 0, slen = C_DIRECTIVE_START.length(), elen = C_DIRECTIVE_END.length();
// Check if any jsp name references occur in the file
int i1 = page.indexOf(C_DIRECTIVE_START);
while (i1 >= 0) {
// Parse the file and replace jsp name references
i2 = page.indexOf(C_DIRECTIVE_END, i1 + slen);
if (i2 > i1) {
String directive = page.substring(i1 + slen, i2);
if (DEBUG > 2) System.err.println("JspLoader: Detected " + C_DIRECTIVE_START + directive + C_DIRECTIVE_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 = controller.getCurrentRequest().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, controller, updates);
jspname = getJspUri(jsp.getAbsolutePath(), controller.getCurrentRequest().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 " + C_DIRECTIVE_START + directive + C_DIRECTIVE_END);
}
}
buf.append(page.substring(p0, i1 + t6));
buf.append(directive);
p0 = i2 + t7;
i1 = page.indexOf(C_DIRECTIVE_START, p0);
}
}
if (i2 > 0) {
buf.append(page.substring(p0, page.length()));
// Encoding project:
// Now we are ready to store String data in file system.
// To convert String to bytes we also need to provide
// some encoding. The default (by the JSP standard) encoding
// for JSP is ISO-8859-1.
contents = buf.toString().getBytes(jspEncoding);
} else {
// Encoding project:
// Contents of original file where not modified,
// just translate to the required JSP encoding (if necessary)
contents = Encoder.changeEncoding(contents, A_OpenCms.getDefaultEncoding(), jspEncoding);
}
fs.write(contents);
fs.close();
if (I_CmsLogChannels.C_LOGGING && A_OpenCms.isLogging(I_CmsLogChannels.C_OPENCMS_INFO))
A_OpenCms.log(I_CmsLogChannels.C_OPENCMS_INFO, "Updated JSP file \"" + jspfilename + "\" for resource \"" + file.getAbsolutePath() + "\"") ;
} catch (FileNotFoundException e) {
throw new ServletException("JspLauncher: Could not write to file '" + f.getName() + "'\n" + e, e);
}
}
return jspfilename;
}
/**
* Does the job of including the JSP,
* this method should usually be called from a <code>CmsFlexRequestDispatcher</code> only.<p>
*
* This method is called directly if the element is
* called as a sub-element from another I_CmsResourceLoader.<p>
*
* One of the tricky issues is the correct cascading of the Exceptions,
* so that you are able to identify the true origin of the problem.
* This ia achived by imprinting a String C_EXCEPTION_PREFIX to the
* exception message.
*
* @param cms used to access the OpenCms VFS
* @param file the reqested JSP file resource in the VFS
* @param req the current request
* @param res the current response
*
* @throws ServletException might be thrown in the process of including the JSP
* @throws IOException might be thrown in the process of including the JSP
*
* @see com.opencms.flex.cache.CmsFlexRequestDispatcher
*/
public void service(CmsObject cms, CmsResource file, ServletRequest req, ServletResponse res)
throws ServletException, IOException {
try {
CmsFlexController controller = (CmsFlexController)req.getAttribute(CmsFlexController.ATTRIBUTE_NAME);
// Get JSP target name on "real" file system
String target = updateJsp(cms, file, req, controller, new HashSet(11));
// Important: Indicate that all output must be buffered
controller.getCurrentResponse().setOnlyBuffering(true);
// Dispatch to external file
controller.getCurrentRequest().getRequestDispatcherToExternal(file.getAbsolutePath(), target).include(req, res);
} catch (ServletException e) {
// Check if this Exception has already been marked
String msg = e.getMessage();
if (DEBUG > 1) System.err.println("JspLauncher: Caught ServletException " + e );
if ((msg != null) && msg.startsWith(C_LOADER_EXCEPTION_PREFIX)) throw e;
// Not marked, imprint current JSP file and stack trace
throw new ServletException(C_LOADER_EXCEPTION_PREFIX + " '" + file.getAbsolutePath() + "'\n\nRoot cause:\n" + Utils.getStackTrace(e) + "\n--------------- End of root cause.\n", e);
} catch (Exception e) {
// Imprint current JSP file and stack trace
throw new ServletException(C_LOADER_EXCEPTION_PREFIX + " '" + file.getAbsolutePath() + "'\n\nRoot cause:\n" + Utils.getStackTrace(e) + "\n--------------- End of root cause.\n", e);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -