?? velocitycommand.java
字號:
package dark.web.frame.velocity.command;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import dark.web.frame.Value;
import dark.web.frame.command.AbstractCommand;
import org.apache.velocity.Template;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.io.VelocityWriter;
import org.apache.velocity.runtime.RuntimeSingleton;
import org.apache.velocity.tools.view.ToolboxManager;
import org.apache.velocity.tools.view.context.ChainedContext;
import org.apache.velocity.util.SimplePool;
/**
* <p>Title: VelocityCommand</p>
* <p>Description: 支持Velocity的Command處理超類
* 根據org.apache.velocity.servlet.VelocityServlet進行修改,
* 從而將Velocity整合進dwf框架</p>
* <p>Copyright: Copyright (c) 2005</p>
* <p>Company: DIS</p>
* <p>Create Time: 2005-2-28 15:40:34</p>
* @author <a href="mailto:dark_he@hotmail.com">darkhe</a>
* @version 1.0
*/
public abstract class VelocityCommand extends AbstractCommand
{
/** Cache of writers */
private static SimplePool writerPool = new SimplePool(40);
/** A reference to the toolbox manager. */
protected ToolboxManager toolboxManager = null;
private String contentType = "text/html";
/** encoding for the output stream */
private String outputEncoding = "ISO-8859-1";
/**
* Whether we've logged a deprecation warning for
* ServletResponse's <code>getOutputStream()</code>.
* @since VelocityTools 1.1
*/
private boolean warnOfOutputStreamDeprecation = true;
public Template process(
HttpServletRequest request,
HttpServletResponse response,
Context ctx)
throws Exception
{
Value v = loadValue(request);
Template t = process(request, response, ctx, v);
saveValue(v, request);
ctx.put("Value", v);
ctx.put("Request", request);
ctx.put("Response", response);
ctx.put("Session", request.getSession());
return t;
}
/**
* 子類必須實現當前方法以實現業務邏輯
* @param request
* @param response
* @param context
* @param v
* @return
* @throws Exception
*/
public abstract Template process(
HttpServletRequest request,
HttpServletResponse response,
Context context,
Value v)
throws Exception;
/**
* @throws ServletException
* @throws IOException
* @see dark.web.frame.Command#process()
*/
public void process() throws ServletException, IOException
{
Context context = null;
HttpServletRequest request = getRequest();
HttpServletResponse response = getResponse();
try
{
/*
* first, get a context
*/
context = createContext(request, response);
/*
* set the content type
*/
response.setContentType(contentType);
/*
* let someone handle the request
*/
Template template = process(request, response, context);
/*
* bail if we can't find the template
*/
if (template == null)
{
log.warn("template is null");
return;
}
/*
* now merge it
*/
mergeTemplate(template, context, response);
}
catch (Exception e)
{
/*
* call the error handler to let the derived class
* do something useful with this failure.
*/
error(request, response, e);
}
finally
{
/*
* call cleanup routine to let a derived class do some cleanup
*/
requestCleanup(request, response, context);
}
}
/**
* Cleanup routine called at the end of the request processing sequence
* allows a derived class to do resource cleanup or other end of
* process cycle tasks. This default implementation does nothing.
*
* @param request servlet request from client
* @param response servlet reponse
* @param context Context created by the {@link #createContext}
*/
protected void requestCleanup(HttpServletRequest request,
HttpServletResponse response,
Context context)
{
}
/**
* <p>Handle the template processing request.</p>
*
* @param request client request
* @param response client response
* @param ctx VelocityContext to fill
*
* @return Velocity Template object or null
*/
protected Template handleRequest(HttpServletRequest request,
HttpServletResponse response,
Context ctx)
throws Exception
{
// If we get here from RequestDispatcher.include(), getServletPath()
// will return the original (wrong) URI requested. The following special
// attribute holds the correct path. See section 8.3 of the Servlet
// 2.3 specification.
String path = (String)request.getAttribute("javax.servlet.include.servlet_path");
if (path == null)
{
path = request.getServletPath();
}
return getTemplate(path);
}
/**
* <p>Creates and returns an initialized Velocity context.</p>
*
* A new context of class {@link ChainedContext} is created and
* initialized.
*
* @param request servlet request from client
* @param response servlet reponse to client
*/
protected Context createContext(HttpServletRequest request,
HttpServletResponse response)
{
ChainedContext ctx = new ChainedContext(null, request, response, getServletContext());
/* if we have a toolbox manager, get a toolbox from it */
if (toolboxManager != null)
{
ctx.setToolbox(toolboxManager.getToolboxContext(ctx));
}
return ctx;
}
/**
* Retrieves the requested template.
*
* @param name The file name of the template to retrieve relative to the
* template root.
* @return The requested template.
* @throws ResourceNotFoundException if template not found
* from any available source.
* @throws ParseErrorException if template cannot be parsed due
* to syntax (or other) error.
* @throws Exception if an error occurs in template initialization
*/
public Template getTemplate(String name)
throws ResourceNotFoundException, ParseErrorException, Exception
{
return RuntimeSingleton.getTemplate(name);
}
/**
* Retrieves the requested template with the specified character encoding.
*
* @param name The file name of the template to retrieve relative to the
* template root.
* @param encoding the character encoding of the template
* @return The requested template.
* @throws ResourceNotFoundException if template not found
* from any available source.
* @throws ParseErrorException if template cannot be parsed due
* to syntax (or other) error.
* @throws Exception if an error occurs in template initialization
*/
public Template getTemplate(String name, String encoding)
throws ResourceNotFoundException, ParseErrorException, Exception
{
return RuntimeSingleton.getTemplate(name, encoding);
}
/**
* Merges the template with the context. Only override this if you really, really
* really need to. (And don't call us with questions if it breaks :)
*
* @param template template object returned by the handleRequest() method
* @param context Context created by the {@link #createContext}
* @param response servlet reponse (used to get a Writer)
*/
protected void mergeTemplate(Template template,
Context context,
HttpServletResponse response)
throws ResourceNotFoundException, ParseErrorException,
MethodInvocationException, IOException,
UnsupportedEncodingException, Exception
{
VelocityWriter vw = null;
Writer writer = getResponseWriter(response);
try
{
vw = (VelocityWriter)writerPool.get();
if (vw == null)
{
vw = new VelocityWriter(writer, 4 * 1024, true);
}
else
{
vw.recycle(writer);
}
template.merge(context, vw);
}
finally
{
if (vw != null)
{
try
{
// flush and put back into the pool
// don't close to allow us to play
// nicely with others.
vw.flush();
/* This hack sets the VelocityWriter's internal ref to the
* PrintWriter to null to keep memory free while
* the writer is pooled. See bug report #18951 */
vw.recycle(null);
writerPool.put(vw);
}
catch (Exception e)
{
Velocity.debug("VelocityViewServlet: " +
"Trouble releasing VelocityWriter: " +
e.getMessage());
}
}
}
}
/**
* Invoked when there is an error thrown in any part of doRequest() processing.
* <br><br>
* Default will send a simple HTML response indicating there was a problem.
*
* @param request original HttpServletRequest from servlet container.
* @param response HttpServletResponse object from servlet container.
* @param e Exception that was thrown by some other part of process.
*/
protected void error(HttpServletRequest request,
HttpServletResponse response,
Exception e)
throws ServletException
{
try
{
StringBuffer html = new StringBuffer();
html.append("<html>\n");
html.append("<head><title>Error</title></head>\n");
html.append("<body>\n");
html.append("<h2>VelocityCommand : Error processing the template</h2>\n");
Throwable cause = e;
String why = cause.getMessage();
if (why != null && why.trim().length() > 0)
{
html.append(why);
html.append("\n<br>\n");
}
// if it's an MIE, i want the real stack trace!
if (cause instanceof MethodInvocationException)
{
// get the real cause
cause = ((MethodInvocationException)cause).getWrappedThrowable();
}
StringWriter sw = new StringWriter();
cause.printStackTrace(new PrintWriter(sw));
html.append("<pre>\n");
html.append(sw.toString());
html.append("</pre>\n");
html.append("</body>\n");
html.append("</html>");
getResponseWriter(response).write(html.toString());
}
catch (Exception e2)
{
// clearly something is quite wrong.
// let's log the new exception then give up and
// throw a servlet exception that wraps the first one
Velocity.error("VelocityCommand: Exception while printing error screen: "+e2);
throw new ServletException(e);
}
}
/**
* <p>Procure a Writer with correct encoding which can be used
* even if HttpServletResponse's <code>getOutputStream()</code> method
* has already been called.</p>
*
* <p>This is a transitional method which will be removed in a
* future version of Velocity. It is not recommended that you
* override this method.</p>
*
* @param response The response.
* @return A <code>Writer</code>, possibly created using the
* <code>getOutputStream()</code>.
*/
protected Writer getResponseWriter(HttpServletResponse response)
throws UnsupportedEncodingException, IOException
{
Writer writer = null;
try
{
writer = response.getWriter();
}
catch (IllegalStateException e)
{
// ASSUMPTION: We already called getOutputStream(), so
// calls to getWriter() fail. Use of OutputStreamWriter
// assures our desired character set
if (this.warnOfOutputStreamDeprecation)
{
this.warnOfOutputStreamDeprecation = false;
Velocity.warn("VelocityCommand: " +
"Use of ServletResponse's getOutputStream() " +
"method with VelocityViewServlet is " +
"deprecated -- support will be removed in " +
"an upcoming release");
}
// Assume the encoding has been set via setContentType().
String encoding = response.getCharacterEncoding();
if (encoding == null)
{
encoding = outputEncoding;
}
writer = new OutputStreamWriter(response.getOutputStream(),
encoding);
}
return writer;
}
/**
* @return
*/
public String getContentType()
{
return contentType;
}
/**
* @param string
*/
public void setContentType(String string)
{
contentType = string;
}
/**
* @return
*/
public ToolboxManager getToolboxManager()
{
return toolboxManager;
}
/**
* @param manager
*/
public void setToolboxManager(ToolboxManager manager)
{
toolboxManager = manager;
}
/**
* @return
*/
public String getOutputEncoding()
{
return outputEncoding;
}
/**
* @param string
*/
public void setOutputEncoding(String string)
{
outputEncoding = string;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -