cmsflexrequestdispatcher.java
来自「java 编写的程序」· Java 代码 · 共 282 行
JAVA
282 行
/*
* File : $Source: /usr/local/cvs/opencms/src/com/opencms/flex/cache/Attic/CmsFlexRequestDispatcher.java,v $
* Date : $Date: 2002/05/10 21:07:30 $
* Version: $Revision: 1.1.2.1.2.1 $
*
* This library is part of OpenCms -
* the Open Source Content Mananagement System
*
* Copyright (C) 2002 The OpenCms Group
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* For further information about OpenCms, please see the
* OpenCms Website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.opencms.flex.cache;
import javax.servlet.ServletException;
/**
* Implementation of the javax.servlet.RequestDispatcher interface.
* This dispatcher will load data from 3 different data sources:
* <ol>
* <li>Form the "real" system Filesystem (e.g. for JSP pages)
* <li>From the OpenCms VFS
* <li>From the Flex cache
* </ol>
*
* @author Alexander Kandzior (a.kandzior@alkacon.com)
* @version $Revision: 1.1.2.1.2.1 $
*/
public class CmsFlexRequestDispatcher implements javax.servlet.RequestDispatcher {
/** The "real" RequestDispatcher, used when a true include (to the file system) is needed. */
private javax.servlet.RequestDispatcher m_rd = null;
/** The target that will be included by the RequestDispatcher. */
private String m_target = null;
/** The external target that will be included by the RequestDispatcher, needed if this is not a dispatcher to a cms resource */
private String m_ext_target = null;
/** The cache where results from the dispatcher will be saved in. */
private CmsFlexCache m_cache = null;
/** The CmsObject that is needed for authorization of internal calls. */
private com.opencms.file.CmsObject m_cms = null;
/** Internal DEBUG flag */
private int DEBUG = 0;
/**
* Creates a new instance of CmsFlexRequestDispatcher.
*
* @param rd The "real" dispatcher, used for include call to file system.
* @param target The target that the request will be dispatched to.
* @param cache The cache used for delivering and storing of cached pages.
* @param cms The CmsObject that is needed for authorization of internal calls to the OpenCms VFS.
*/
public CmsFlexRequestDispatcher(javax.servlet.RequestDispatcher rd, String target, CmsFlexCache cache, com.opencms.file.CmsObject cms) {
this(rd, target, null, cache, cms);
}
/**
* Creates a new instance of CmsFlexRequestDispatcher.
*
* @param rd The "real" dispatcher, used for include call to file system.
* @param target The cms resource that represents the external target.
* @param ext_target The external target that the request will be dispatched to.
* @param cache The cache used for delivering and storing of cached pages.
* @param cms The CmsObject that is needed for authorization of internal calls to the OpenCms VFS.
*/
public CmsFlexRequestDispatcher(javax.servlet.RequestDispatcher rd, String target, String ext_target, CmsFlexCache cache, com.opencms.file.CmsObject cms) {
m_rd = rd;
m_target = target;
m_ext_target = ext_target;
m_cache = cache;
m_cms = cms;
}
/**
* Wrapper for the standard servlet API call.
* Forward calls are actually NOT wrapped by OpenCms as of now.
* So they should not be used in JSP pages or servlets.
*
* @param servletRequest The servlet request
* @param servletResponse The servlet response
* @throws ServletException In case something goes wrong
* @throws IOException In case something goes wrong
*/
public void forward(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse)
throws ServletException, java.io.IOException {
m_rd.forward(servletRequest, servletResponse);
}
/**
* Wrapper for the standard servlet API call.
* If you use standard include(), the call will be done
* by the standard request dispatcher.
* In case you want to include somthing from the Cms VFS,
* use includeFromCms() instead.
*
* @param servletRequest The servlet request
* @param servletResponse The servlet response
* @throws ServletException In case something goes wrong
* @throws IOException In case something goes wrong
*/
public void include(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse)
throws ServletException, java.io.IOException {
m_rd.include(servletRequest, servletResponse);
}
/**
* Wrapper for dispatching to a file from the OpenCms VFS.<p>
*
* It was choosen NOT to overload the standard API include() call,
* since standard JSP might expect the standard behaviour from
* the RequestDispatcher, i.e. loading the files form the file system.
*
* This method will dispatch to cache, to real file system or
* to the OpenCms VFS, whatever is needed.<p>
*
* This method is much more complex then it sould be because of the internal buffering of JSP pages.
* Because of that I can not just intercept and buffer the stream, since I don't have
* access to it (it is wrapped internally in the JSP pages, which have their own buffer).
* That leads to a solution where the data is first written to the bufferd stream,
* but without includes. Then it is parsed again later
* (in response.processCacheEntry()), enriched with the
* included elements that have been ommitted in the first case.
* I would love to see a simpler solution, but this works for now.
*
* @param req The servlet request
* @param res The servlet response
* @throws ServletException In case something goes wrong
* @throws IOException In case something goes wrong
*/
// public void includeFromCms(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse)
public void include(CmsFlexRequest req, CmsFlexResponse res)
throws ServletException, java.io.IOException {
// TODO: Currently all requesty are looked for in the cms only -> what about include calls to resources outside of cms???
if (DEBUG > 0) System.err.println("FlexDispatcher: Include called with target=" + m_target);
if (m_ext_target != null) {
// This is an external include, probably to a JSP page, dispatch with system dispatcher
m_rd.include(req, res);
return;
}
if (req.containsIncludeCall(m_target)) {
// This resource was already included earlier, so we have a (probably endless) inclusion loop
throw new ServletException("FlexDispatcher: Dectected inclusion loop for target " + m_target);
} else {
req.addInlucdeCall(m_target);
}
// Do nothing if response is already finished (probably as a result of an earlier redirect)
if (res.isSuspended()) return;
// Indicate to response that all further output or headers are result of include calls
res.setCmsIncludeMode(true);
// Create wrapper for request & response
CmsFlexRequest w_req = new CmsFlexRequest(req, m_target);
CmsFlexResponse w_res = new CmsFlexResponse(res);
CmsFlexCacheEntry entry = null;
if (req.isCacheable()) {
// Caching is on, check if requested resource is already in cache
entry = m_cache.get(w_req.getCmsCacheKey());
if (entry != null) {
// The target is already in the cache
try {
if (DEBUG > 0) System.err.println("FlexDispatcher: Loading file from cache for " + m_target);
entry.service(w_req, w_res);
} catch (com.opencms.core.CmsException e) {
throw new ServletException("FlexDispatcher: Error while loading file from cache for " + m_target + "\n" + e, e);
}
} else {
// Cache is on and resource is not yet cached, so we need to read the cache key for the response
CmsFlexCacheKey res_key = m_cache.getKey(CmsFlexCacheKey.getKeyName(m_target, w_req.isOnline()));
if (res_key != null) {
// Key already in cache, reuse it
w_res.setCmsCacheKey(res_key);
} else {
// Cache key is unknown, read key from properties
String cache = null;
try {
// Read caching property from requested VFS resource
cache = m_cms.readProperty(m_target, com.opencms.flex.I_CmsResourceLoader.C_LOADER_CACHEPROPERTY);
m_cache.putKey(w_res.setCmsCacheKey(m_target, cache, req.isOnline()));
} catch (com.opencms.core.CmsException e) {
if (e.getType() == e.C_FLEX_CACHE) {
// Invalid key is ignored but logged, used key is cache=never
log("Invalid cache key for external resource \"" + m_target + "\": " + cache);
} else {
// All other errors are not handled here
throw new ServletException("FlexDispatcher: Error while loading cache properties for " + m_target + "\n" + e, e);
}
}
if (DEBUG > 1) System.err.println("FlexDispatcher: Cache properties for file " + m_target + " are: " + cache);
}
}
}
if (entry == null) {
// The target is not cached (or caching off), so load it with the internal resource loader
com.opencms.launcher.CmsLauncherManager manager = m_cms.getLauncherManager();
com.opencms.flex.I_CmsResourceLoader loader = null;
String variation = null;
// Check cache keys to see if the result can be cached
if (w_req.isCacheable()) variation = w_res.getCmsCacheKey().matchRequestKey(w_req.getCmsCacheKey());
// Indicate to the response if caching is not required
w_res.setCmsCachingRequired(variation != null);
com.opencms.file.CmsResource resource = null;
try {
resource = m_cms.readFileHeader(m_target);
int type = resource.getLauncherType();
if (DEBUG > 0) System.err.println("FlexDispatcher: Loading resource type " + type);
loader = (com.opencms.flex.I_CmsResourceLoader)manager.getLauncher(type);
} catch (java.lang.ClassCastException e) {
throw new ServletException("FlexDispatcher: CmsResourceLoader interface not implemented for cms resource " + m_target + "\n" + e, e);
} catch (com.opencms.core.CmsException e) {
// File might not exist or no read permissions
throw new ServletException("FlexDispatcher: Error while reading header for cms resource " + m_target + "\n" + e, e);
}
try {
if (DEBUG > 0) System.err.println("FlexDispatcher: Internal call, loading file using loader.service() for " + m_target);
loader.service(m_cms, resource, w_req, w_res);
} catch (com.opencms.core.CmsException e) {
throw new ServletException("FlexDispatcher: Error in internal call, loading file using loader.service() for " + m_target + "\n" + e, e);
}
entry = w_res.processCacheEntry();
if ((entry != null) && (variation != null) && w_req.isCacheable()) {
m_cache.put(w_res.getCmsCacheKey(), entry, variation);
}
}
if (res.hasIncludeList()) {
// Special case: This indicates that the output was not yet displayed
java.util.Map headers = w_res.getHeaders();
byte[] result = w_res.getWriterBytes();
if (DEBUG > 1) System.err.println("Non-display include call - Result of include is:\n" + new String(result));
res.processHeaders(headers, res);
res.addToIncludeResults(result);
}
// Indicate to response that include is finished
res.setCmsIncludeMode(false);
req.removeIncludeCall(m_target);
}
/**
* Logs a message to the OpenCms log in the channel "flex_cache".
*
* @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_CACHE, "[CmsFlexRequestDispatcher] " + message);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?