cmsjsploader.java
来自「找了很久才找到到源代码」· Java 代码 · 共 1,284 行 · 第 1/4 页
JAVA
1,284 行
buf.append(content.substring(p0, content.length()));
content = buf.toString();
}
return content;
}
/**
* Parses all jsp link macros, and replace them by the right target path.<p>
*
* @param content the content to parse
* @param controller the request controller
*
* @return the parsed content
*/
private String parseJspLinkMacros(String content, CmsFlexController controller) {
CmsJspLinkMacroResolver macroResolver = new CmsJspLinkMacroResolver(controller.getCmsObject(), null, true);
return macroResolver.resolveMacros(content);
}
/**
* @see org.opencms.loader.I_CmsResourceLoader#service(org.opencms.file.CmsObject, org.opencms.file.CmsResource, javax.servlet.ServletRequest, javax.servlet.ServletResponse)
*/
public void service(CmsObject cms, CmsResource resource, ServletRequest req, ServletResponse res)
throws ServletException, IOException, CmsLoaderException {
CmsFlexController controller = CmsFlexController.getController(req);
// get JSP target name on "real" file system
String target = updateJsp(resource, controller, new HashSet(8));
// important: Indicate that all output must be buffered
controller.getCurrentResponse().setOnlyBuffering(true);
// dispatch to external file
controller.getCurrentRequest().getRequestDispatcherToExternal(cms.getSitePath(resource), target).include(
req,
res);
}
/**
* @see org.opencms.loader.I_CmsFlexCacheEnabledLoader#setFlexCache(org.opencms.flex.CmsFlexCache)
*/
public void setFlexCache(CmsFlexCache cache) {
m_cache = cache;
// output setup information
if (CmsLog.INIT.isInfoEnabled()) {
CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_ADD_FLEX_CACHE_0));
}
}
/**
* Delivers the plain uninterpreted resource with escaped XML.<p>
*
* This is intended for viewing historical versions.<p>
*
* @param cms the initialized CmsObject which provides user permissions
* @param file the requested OpenCms VFS resource
* @param req the servlet request
* @param res the servlet response
*
* @throws IOException might be thrown by the servlet environment
* @throws CmsException in case of errors acessing OpenCms functions
*/
private void showSource(CmsObject cms, CmsResource file, HttpServletRequest req, HttpServletResponse res)
throws CmsException, IOException {
CmsResource historyResource = (CmsResource)CmsHistoryResourceHandler.getHistoryResource(req);
if (historyResource == null) {
historyResource = file;
}
CmsFile historyFile = cms.readFile(historyResource);
String content = new String(historyFile.getContents());
// change the content-type header so that browsers show plain text
res.setContentLength(content.length());
res.setContentType("text/plain");
Writer out = res.getWriter();
out.write(content);
}
/**
* 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 resource the reqested JSP file resource in the VFS
* @param controller the controller for the JSP integration
* @param updatedFiles 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
* @throws CmsLoaderException if the resource type can not be read
*/
private String updateJsp(CmsResource resource, CmsFlexController controller, Set updatedFiles)
throws IOException, ServletException, CmsLoaderException {
String jspVfsName = resource.getRootPath();
String extension;
boolean isHardInclude;
int loaderId = OpenCms.getResourceManager().getResourceType(resource.getTypeId()).getLoaderId();
if ((loaderId == CmsJspLoader.RESOURCE_LOADER_ID) && (!jspVfsName.endsWith(JSP_EXTENSION))) {
// this is a true JSP resource that does not end with ".jsp"
extension = JSP_EXTENSION;
isHardInclude = false;
} else {
// not a JSP resource or already ends with ".jsp"
extension = "";
// if this is a JSP we don't treat it as hard include
isHardInclude = (loaderId != CmsJspLoader.RESOURCE_LOADER_ID);
}
String jspTargetName = CmsFileUtil.getRepositoryName(
m_jspWebAppRepository,
jspVfsName + extension,
controller.getCurrentRequest().isOnline());
// check if page was already updated
if (updatedFiles.contains(jspTargetName)) {
// no need to write the already included file to the real FS more then once
return jspTargetName;
}
String jspPath = CmsFileUtil.getRepositoryName(
m_jspRepository,
jspVfsName + extension,
controller.getCurrentRequest().isOnline());
File d = new File(jspPath).getParentFile();
if ((d == null) || (d.exists() && !(d.isDirectory() && d.canRead()))) {
CmsMessageContainer message = Messages.get().container(Messages.LOG_ACCESS_DENIED_1, jspPath);
LOG.error(message.key());
// can not continue
throw new ServletException(message.key());
}
if (!d.exists()) {
// create directory structure
d.mkdirs();
}
// check if the JSP must be updated
boolean mustUpdate = false;
File f = new File(jspPath);
if (!f.exists()) {
// file does not exist in real FS
mustUpdate = true;
// make sure the parent folder exists
File folder = f.getParentFile();
if (!folder.exists()) {
boolean success = folder.mkdirs();
if (!success) {
LOG.error(org.opencms.db.Messages.get().getBundle().key(
org.opencms.db.Messages.LOG_CREATE_FOLDER_FAILED_1,
folder.getAbsolutePath()));
}
}
} else if (f.lastModified() <= resource.getDateLastModified()) {
// file in real FS is older then file in VFS
mustUpdate = true;
} else if (controller.getCurrentRequest().isDoRecompile()) {
// recompile is forced with parameter
mustUpdate = true;
} else {
// update strong link dependencies
mustUpdate = updateStrongLinks(resource, controller, updatedFiles);
}
if (mustUpdate) {
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.get().getBundle().key(Messages.LOG_WRITING_JSP_1, jspTargetName));
}
updatedFiles.add(jspTargetName);
byte[] contents;
String encoding;
try {
CmsObject cms = controller.getCmsObject();
contents = cms.readFile(resource).getContents();
// check the "content-encoding" property for the JSP, use system default if not found on path
encoding = cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_CONTENT_ENCODING, true).getValue();
if (encoding == null) {
encoding = OpenCms.getSystemInfo().getDefaultEncoding();
} else {
encoding = CmsEncoder.lookupEncoding(encoding.trim(), encoding);
}
} catch (CmsException e) {
controller.setThrowable(e, jspVfsName);
throw new ServletException(
Messages.get().getBundle().key(Messages.ERR_LOADER_JSP_ACCESS_1, jspVfsName),
e);
}
try {
// parse the JSP and modify OpenCms critical directives
contents = parseJsp(contents, encoding, controller, updatedFiles, isHardInclude);
if (LOG.isInfoEnabled()) {
// check for existing file and display some debug info
LOG.info(Messages.get().getBundle().key(
Messages.LOG_JSP_PERMCHECK_4,
new Object[] {
f.getAbsolutePath(),
Boolean.valueOf(f.exists()),
Boolean.valueOf(f.isFile()),
Boolean.valueOf(f.canWrite())}));
}
// write the parsed JSP content to the real FS
synchronized (this) {
// this must be done only one file at a time
FileOutputStream fs = new FileOutputStream(f);
fs.write(contents);
fs.close();
}
if (LOG.isInfoEnabled()) {
LOG.info(Messages.get().getBundle().key(Messages.LOG_UPDATED_JSP_2, jspTargetName, jspVfsName));
}
} catch (FileNotFoundException e) {
throw new ServletException(
Messages.get().getBundle().key(Messages.ERR_LOADER_JSP_WRITE_1, f.getName()),
e);
}
}
// update "last modified" and "expires" date on controller
controller.updateDates(f.lastModified(), CmsResource.DATE_EXPIRED_DEFAULT);
return jspTargetName;
}
/**
* Updates a JSP page in the "real" file system in case the VFS resource has changed based on the resource name.<p>
*
* Gernates a resource based on the provided name and calls {@link #updateJsp(CmsResource, CmsFlexController, Set)}.<p>
*
* @param vfsName the name of the JSP file resource in the VFS
* @param controller the controller for the JSP integration
* @param updatedFiles a Set containing all JSP pages that have been already updated
* @return the file name of the updated JSP in the "real" FS
*/
private String updateJsp(String vfsName, CmsFlexController controller, Set updatedFiles) {
String jspVfsName = CmsLinkManager.getAbsoluteUri(vfsName, controller.getCurrentRequest().getElementRootPath());
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.get().getBundle().key(Messages.LOG_UPDATE_JSP_1, jspVfsName));
}
String jspRfsName;
try {
// create an OpenCms user context that operates in the root site
CmsObject cms = OpenCms.initCmsObject(controller.getCmsObject());
cms.getRequestContext().setSiteRoot("");
CmsResource includeResource = cms.readResource(jspVfsName);
// make sure the jsp referenced file is generated
jspRfsName = updateJsp(includeResource, controller, updatedFiles);
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.get().getBundle().key(Messages.LOG_NAME_REAL_FS_1, jspRfsName));
}
} catch (Exception e) {
jspRfsName = null;
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.get().getBundle().key(Messages.LOG_ERR_UPDATE_1, jspVfsName), e);
}
}
return jspRfsName;
}
/**
* Updates all jsp files that include the given jsp file using the 'link.strong' macro.<p>
*
* @param resource the current updated jsp file
* @param controller the controller for the jsp integration
* @param updatedFiles the already updated files
*
* @return <code>true</code> if the given JSP file should be updated due to dirty included files
*
* @throws ServletException might be thrown in the process of including the JSP
* @throws IOException might be thrown in the process of including the JSP
* @throws CmsLoaderException if the resource type can not be read
*/
private boolean updateStrongLinks(CmsResource resource, CmsFlexController controller, Set updatedFiles)
throws CmsLoaderException, IOException, ServletException {
int numberOfUpdates = updatedFiles.size();
CmsObject cms = controller.getCmsObject();
CmsRelationFilter filter = CmsRelationFilter.TARGETS.filterType(CmsRelationType.JSP_STRONG);
Iterator it;
try {
it = cms.getRelationsForResource(cms.getSitePath(resource), filter).iterator();
} catch (CmsException e) {
// should never happen
if (LOG.isErrorEnabled()) {
LOG.error(e.getLocalizedMessage(), e);
}
return false;
}
while (it.hasNext()) {
CmsRelation relation = (CmsRelation)it.next();
CmsResource target = null;
try {
target = relation.getTarget(cms, CmsResourceFilter.DEFAULT);
} catch (CmsException e) {
// should never happen
if (LOG.isErrorEnabled()) {
LOG.error(e.getLocalizedMessage(), e);
}
continue;
}
// check if page was already updated
if (updatedFiles.contains(target.getRootPath())) {
// no need to write the included file to the real FS more than once
continue;
}
// update the target
updateJsp(target, controller, updatedFiles);
}
// the current jsp file should be updated only if one of the included jsp has been updated
return numberOfUpdates < updatedFiles.size();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?