AUTO_INCREMENT column for the last row insertion. This
- * is MySQL specific, but exists here for now until we sort out a general purpose mechanism for
- * assigning unique ids.
- *
- * Note: More general purpose: {@link #lastInsertedId(Connection, String, String)
- *
- * @return the most recent ID generated by an insert into an AUTO_INCREMENT table
- * or -1 if it could not be obtained.
- */
- @Deprecated
- public int lastInsertedId (Connection conn)
- throws SQLException;
-
/**
* This method initializes the column value auto-generator described in {@link
- * #lastInsertedId(Connection, String, String)}.
+ * #lastInsertedId}.
*/
public void initializeGenerator (
Connection conn, String table, String column, int first, int step)
diff --git a/src/java/com/samskivert/jdbc/DefaultLiaison.java b/src/java/com/samskivert/jdbc/DefaultLiaison.java
index 369e5823..d48f1d70 100644
--- a/src/java/com/samskivert/jdbc/DefaultLiaison.java
+++ b/src/java/com/samskivert/jdbc/DefaultLiaison.java
@@ -47,7 +47,7 @@ public class DefaultLiaison extends BaseLiaison
return false;
}
- // from DatabaseLiaison
+ @SuppressWarnings("deprecation") // from DatabaseLiaison
public int lastInsertedId (Connection conn) throws SQLException
{
return -1;
diff --git a/src/java/com/samskivert/jdbc/JORARepository.java b/src/java/com/samskivert/jdbc/JORARepository.java
index 978bbac2..d97beeaf 100644
--- a/src/java/com/samskivert/jdbc/JORARepository.java
+++ b/src/java/com/samskivert/jdbc/JORARepository.java
@@ -65,7 +65,7 @@ public abstract class JORARepository extends SimpleRepository
throws SQLException, PersistenceException
{
table.insert(conn, object);
- return liaison.lastInsertedId(conn);
+ return liaison.lastInsertedId(conn, table.getName(), "TODO");
}
});
}
@@ -265,7 +265,7 @@ public abstract class JORARepository extends SimpleRepository
{
if (table.update(conn, object) == 0) {
table.insert(conn, object);
- return liaison.lastInsertedId(conn);
+ return liaison.lastInsertedId(conn, table.getName(), "TODO");
}
return -1;
}
diff --git a/src/java/com/samskivert/jdbc/MySQLLiaison.java b/src/java/com/samskivert/jdbc/MySQLLiaison.java
index 66e21c86..210f8a97 100644
--- a/src/java/com/samskivert/jdbc/MySQLLiaison.java
+++ b/src/java/com/samskivert/jdbc/MySQLLiaison.java
@@ -47,16 +47,9 @@ public class MySQLLiaison extends BaseLiaison
public boolean isTransientException (SQLException sqe)
{
String msg = sqe.getMessage();
- return (msg != null &&
- (msg.indexOf("Lost connection") != -1 ||
- msg.indexOf("link failure") != -1 ||
- msg.indexOf("Broken pipe") != -1));
- }
-
- // from DatabaseLiaison
- public int lastInsertedId (Connection conn) throws SQLException
- {
- return lastInsertedId(conn, null, null);
+ return (msg != null && (msg.indexOf("Lost connection") != -1 ||
+ msg.indexOf("link failure") != -1 ||
+ msg.indexOf("Broken pipe") != -1));
}
// from DatabaseLiaison
diff --git a/src/java/com/samskivert/jdbc/PostgreSQLLiaison.java b/src/java/com/samskivert/jdbc/PostgreSQLLiaison.java
index 413027eb..329adfa5 100644
--- a/src/java/com/samskivert/jdbc/PostgreSQLLiaison.java
+++ b/src/java/com/samskivert/jdbc/PostgreSQLLiaison.java
@@ -49,13 +49,6 @@ public class PostgreSQLLiaison extends BaseLiaison
msg.indexOf("An I/O error occured while sending to the backend") != -1);
}
- // from DatabaseLiaison
- public int lastInsertedId (Connection conn) throws SQLException
- {
- throw new SQLException(
- "No backwards-compatible lastInsertedId() support for PostgreSQL in this code.");
- }
-
// from DatabaseLiaison
public int lastInsertedId (Connection conn, String table, String column) throws SQLException
{
diff --git a/src/java/com/samskivert/jdbc/depot/DepotRepository.java b/src/java/com/samskivert/jdbc/depot/DepotRepository.java
index c9734b54..d116c100 100644
--- a/src/java/com/samskivert/jdbc/depot/DepotRepository.java
+++ b/src/java/com/samskivert/jdbc/depot/DepotRepository.java
@@ -27,6 +27,7 @@ import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import com.samskivert.io.PersistenceException;
import com.samskivert.util.ArrayUtil;
@@ -50,7 +51,7 @@ import com.samskivert.jdbc.depot.expression.ValueExp;
* Provides a base for classes that provide access to persistent objects. Also defines the
* mechanism by which all persistent queries and updates are routed through the distributed cache.
*/
-public class DepotRepository
+public abstract class DepotRepository
{
/**
* Creates a repository with the supplied connection provider and its own private persistence
@@ -59,6 +60,7 @@ public class DepotRepository
protected DepotRepository (ConnectionProvider conprov)
{
_ctx = new PersistenceContext(getClass().getName(), conprov);
+ _ctx.repositoryCreated(this);
}
/**
@@ -67,8 +69,14 @@ public class DepotRepository
protected DepotRepository (PersistenceContext context)
{
_ctx = context;
+ _ctx.repositoryCreated(this);
}
+ /**
+ * Adds the persistent classes used by this repository to the supplied set.
+ */
+ protected abstract void getManagedRecords (SetURI to servlet mapping
- * The mapping process allows the Velocity framework to be invoked for all
- * requests ending in a particular file extension (usually
- * .wm). It is necessary to instruct your servlet engine of
- * choice to invoke the DispatcherServlet for all requests
- * ending in that extension. For Apache/JServ this looks something like
- * this:
+ *
URI to servlet mapping
The mapping process allows the Velocity framework to be
+ * invoked for all requests ending in a particular file extension (usually .wm). It is
+ * necessary to instruct your servlet engine of choice to invoke the DispatcherServlet
+ * for all requests ending in that extension. For Apache/JServ this looks something like this:
*
*
* ApJServAction .wm /servlets/com.samskivert.velocity.Dispatcher ** - * The request URI then defines the path of the template that will be used - * to satisfy the request. To understand how code is selected to go along - * with the request, let's look at an example. Consider the following - * configuration: + * The request URI then defines the path of the template that will be used to satisfy the + * request. To understand how code is selected to go along with the request, let's look at an + * example. Consider the following configuration: * *
* applications=whowhere @@ -98,48 +98,44 @@ import com.samskivert.util.StringUtil; * whowhere.base_pkg=whowhere.logic ** - * This defines an application identified as
whowhere. An
- * application is defined by three parameters, the application identifier,
- * the base_uri, and the base_pkg. The
- * base_uri defines the prefix shared by all pages served by
- * the application and which serves to identify which application to
- * invoke when processing a request. The base_pkg is used to
- * construct the logic classname based on the URI and the
- * base_uri parameter.
+ * This defines an application identified as whowhere. An application is defined by
+ * three parameters, the application identifier, the base_uri, and the
+ * base_pkg. The base_uri defines the prefix shared by all pages served
+ * by the application and which serves to identify which application to invoke when processing a
+ * request. The base_pkg is used to construct the logic classname based on the URI and
+ * the base_uri parameter.
*
- * Now let's look at a sample request to determine how the logic - * classname is resolved. Consider the following request URI: + *
Now let's look at a sample request to determine how the logic classname is + * resolved. Consider the following request URI: * *
* /whowhere/view/trips.wm ** - * It begins with
/whowhere which tells the dispatcher that
- * it's part of the whowhere application. That application's
- * base_uri is then stripped from the URI leaving
- * /view/trips.wm. The slashes are converted into periods to
- * map directories to packages, giving us view.trips.wm.
- * Finally, the base_pkg is prepended and the trailing
- * .wm extension removed.
+ * It begins with /whowhere which tells the dispatcher that it's part of the
+ * whowhere application. That application's base_uri is then stripped
+ * from the URI leaving /view/trips.wm. The slashes are converted into periods to map
+ * directories to packages, giving us view.trips.wm. Finally, the
+ * base_pkg is prepended and the trailing .wm extension removed.
*
* Thus the class invoked to populate the context for this request is
- * whowhere.servlets.view.trips (note that the classname
- * is lowercase which is an intentional choice in resolving
- * conflicting recommendations that classnames should always start with a
- * capital letter and URLs should always be lowercase).
+ * whowhere.servlets.view.trips (note that the classname is lowercase which
+ * is an intentional choice in resolving conflicting recommendations that classnames should always
+ * start with a capital letter and URLs should always be lowercase).
*
- *
The template used to generate the result is loaded based on the
- * full URI, essentially with a call to
- * getTemplate("/whowhere/view/trips.wm") in this example.
- * This is the place where more sophisticated cobranding support could be
- * inserted in the future (ie. if I ever want to use this to develop a
- * cobranded web site).
+ *
The template used to generate the result is loaded based on the full URI, essentially with a
+ * call to getTemplate("/whowhere/view/trips.wm") in this example. This is the place
+ * where more sophisticated cobranding support could be inserted in the future (ie. if I ever want
+ * to use this to develop a cobranded web site).
*
* @see Logic
*/
-public class DispatcherServlet extends VelocityServlet
+public class DispatcherServlet extends HttpServlet
implements MethodExceptionEventHandler
{
+ /** The HTTP content type context key. */
+ public static final String CONTENT_TYPE = "default.contentType";
+
/**
* Performs various initialization.
*/
@@ -148,29 +144,6 @@ public class DispatcherServlet extends VelocityServlet
{
super.init(config);
- // determine the character set we'll use
- _charset = config.getInitParameter(CHARSET_KEY);
- if (_charset == null) {
- _charset = "UTF-8";
- }
- }
-
- /**
- * Clean up after ourselves and our application.
- */
- public void destroy ()
- {
- super.destroy();
- // shutdown our application
- _app.shutdown();
- }
-
- /**
- * Initialize ourselves and our application.
- */
- protected void initVelocity (ServletConfig config)
- throws ServletException
- {
// load up our application configuration
try {
String appcl = config.getInitParameter(APP_CLASS_KEY);
@@ -187,26 +160,62 @@ public class DispatcherServlet extends VelocityServlet
StringUtil.isBlank(logicPkg) ? "" : logicPkg);
} catch (Throwable t) {
- Log.warning("Error instantiating application.");
- Log.logStackTrace(t);
+ throw new ServletException("Error instantiating Application: " + t, t);
}
- // now let velocity initialize itself
- super.initVelocity(config);
+ try {
+ Velocity.init(loadConfiguration(config));
+ } catch (Exception e) {
+ throw new ServletException("Error initializing Velocity: " + e, e);
+ }
+
+ _defaultContentType = RuntimeSingleton.getString(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
+
+ // determine the character set we'll use
+ _charset = config.getInitParameter(CHARSET_KEY);
+ if (_charset == null) {
+ _charset = "UTF-8";
+ }
}
/**
- * We load our velocity properties from the classpath rather than from
- * a file.
+ * Handles HTTP GET requests by calling {@link #doRequest()}.
+ */
+ public void doGet (HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException
+ {
+ doRequest(request, response);
+ }
+
+ /**
+ * Handles HTTP POST requests by calling {@link #doRequest()}.
+ */
+ public void doPost (HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException
+ {
+ doRequest(request, response);
+ }
+
+ /**
+ * Clean up after ourselves and our application.
+ */
+ public void destroy ()
+ {
+ super.destroy();
+ // shutdown our application
+ _app.shutdown();
+ }
+
+ /**
+ * We load our velocity properties from the classpath rather than from a file.
*/
protected Properties loadConfiguration (ServletConfig config)
throws IOException
{
String propsPath = config.getInitParameter(INIT_PROPS_KEY);
if (propsPath == null) {
- throw new IOException(INIT_PROPS_KEY + " must point to " +
- "the velocity properties file in " +
- "the servlet configuration.");
+ throw new IOException(INIT_PROPS_KEY + " must point to the velocity properties file " +
+ "in the servlet configuration.");
}
// config util loads properties files from the classpath
@@ -230,16 +239,15 @@ public class DispatcherServlet extends VelocityServlet
if (props.getProperty("file.resource.loader.path") == null) {
SiteResourceLoader siteLoader = _app.getSiteResourceLoader();
if (siteLoader != null) {
- Log.info("Velocity loading templates from site loader.");
+ log.info("Velocity loading templates from site loader.");
props.setProperty(RuntimeSingleton.RESOURCE_MANAGER_CLASS,
SiteResourceManager.class.getName());
_usingSiteLoading = true;
} else {
// otherwise use a servlet context resource loader
- Log.info("Velocity loading templates from servlet context.");
- props.setProperty(
- RuntimeSingleton.RESOURCE_MANAGER_CLASS,
- ServletContextResourceManager.class.getName());
+ log.info("Velocity loading templates from servlet context.");
+ props.setProperty(RuntimeSingleton.RESOURCE_MANAGER_CLASS,
+ ServletContextResourceManager.class.getName());
}
}
@@ -247,21 +255,18 @@ public class DispatcherServlet extends VelocityServlet
props.setProperty("userdirective", ImportDirective.class.getName());
// configure the servlet context logger
- props.setProperty(RuntimeSingleton.RUNTIME_LOG_LOGSYSTEM_CLASS,
- ServletContextLogger.class.getName());
+ props.put(RuntimeSingleton.RUNTIME_LOG_LOGSYSTEM, new ServletContextLogger());
// now return our augmented properties
return props;
}
/**
- * Loads up the template appropriate for this request, locates and
- * invokes any associated logic class and finally returns the prepared
- * template which will be merged with the prepared context.
+ * Loads up the template appropriate for this request, locates and invokes any associated logic
+ * class and finally returns the prepared template which will be merged with the prepared
+ * context.
*/
- public Template handleRequest (HttpServletRequest req,
- HttpServletResponse rsp,
- Context ctx)
+ public Template handleRequest (HttpServletRequest req, HttpServletResponse rsp, Context ctx)
throws Exception
{
InvocationContext ictx = (InvocationContext)ctx;
@@ -416,9 +421,8 @@ public class DispatcherServlet extends VelocityServlet
public Object methodException (Class clazz, String method, Exception e)
throws Exception
{
- Log.warning("Exception [class=" + clazz.getName() +
- ", method=" + method + "].");
- Log.logStackTrace(e);
+ log.log(Level.WARNING, "Exception [class=" + clazz.getName() +
+ ", method=" + method + "].", e);
return "";
}
@@ -435,19 +439,67 @@ public class DispatcherServlet extends VelocityServlet
}
/**
- * We override this to create a context of our own devising.
+ * Handles all requests (by default).
+ *
+ * @param request HttpServletRequest object containing client request.
+ * @param response HttpServletResponse object for the response.
*/
- protected Context createContext (HttpServletRequest req,
- HttpServletResponse rsp)
+ protected void doRequest (HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException
{
- return new InvocationContext(req, rsp);
+ Context context = null;
+ try {
+ context = new InvocationContext(request, response);
+ setContentType(request, response);
+
+ Template template = handleRequest(request, response, context);
+ if (template != null) {
+ mergeTemplate(template, context, response);
+ }
+
+ } catch (Exception e) {
+ log.log(Level.WARNING, "doRequest failed [uri=" + request.getRequestURI() + "].", e);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+ }
}
/**
- * This method is called to select the appropriate template for this
- * request. The default implementation simply loads the template using
- * Velocity's default template loading services based on the URI
- * provided in the request.
+ * Sets the content type of the response, defaulting to {@link #defaultContentType} if not
+ * overriden. Delegates to {@link #chooseCharacterEncoding(HttpServletRequest)} to select the
+ * appropriate character encoding.
+ */
+ protected void setContentType (HttpServletRequest request, HttpServletResponse response)
+ {
+ String contentType = _defaultContentType;
+ int index = contentType.lastIndexOf(';') + 1;
+ if (index <= 0 || (index < contentType.length() &&
+ contentType.indexOf("charset", index) == -1)) {
+ // append the character encoding which we'd like to use
+ String encoding = chooseCharacterEncoding(request);
+ if (!DEFAULT_OUTPUT_ENCODING.equalsIgnoreCase(encoding)) {
+ contentType += "; charset=" + encoding;
+ }
+ }
+ response.setContentType(contentType);
+ }
+
+ /**
+ * Chooses the output character encoding to be used as the value for the "charset=" portion of
+ * the HTTP Content-Type header (and thus returned by
+ * response.getCharacterEncoding()). Called by {@link #setContentType} if an
+ * encoding isn't already specified by Content-Type. By default, chooses the value of
+ * RuntimeSingleton's output.encoding property.
+ */
+ protected String chooseCharacterEncoding (HttpServletRequest request)
+ {
+ return RuntimeSingleton.getString(
+ RuntimeConstants.OUTPUT_ENCODING, DEFAULT_OUTPUT_ENCODING);
+ }
+
+ /**
+ * This method is called to select the appropriate template for this request. The default
+ * implementation simply loads the template using Velocity's default template loading services
+ * based on the URI provided in the request.
*
* @param ctx The context of this request.
*
@@ -458,20 +510,62 @@ public class DispatcherServlet extends VelocityServlet
{
String path = ctx.getRequest().getServletPath();
if (_usingSiteLoading) {
- // if we're using site resource loading, we need to prefix the path
- // with the site identifier
+ // if we're using site resource loading, we need to prefix the path with the site
+ // identifier
path = siteId + ":" + path;
}
- // Log.info("Loading template [path=" + path + "].");
+ // log.info("Loading template [path=" + path + "].");
return RuntimeSingleton.getTemplate(path);
}
/**
- * This method is called to select the appropriate logic for this
- * request URI.
+ * Merges the template with the context.
*
- * @return The logic to be used in generating the response or null if
- * no logic could be matched.
+ * @param template template object returned by the {@link #handleRequest} method.
+ * @param context context created by the {@link #createContext} method.
+ * @param response servlet reponse (use this to get the output stream or writer).
+ */
+ protected void mergeTemplate (Template template, Context context, HttpServletResponse response)
+ throws ResourceNotFoundException, ParseErrorException, MethodInvocationException,
+ IOException, UnsupportedEncodingException, Exception
+ {
+ ServletOutputStream output = response.getOutputStream();
+ // ASSUMPTION: response.setContentType() has been called.
+ String encoding = response.getCharacterEncoding();
+
+ VelocityWriter vw = null;
+ try {
+ vw = (VelocityWriter)_writerPool.get();
+ if (vw == null) {
+ vw = new VelocityWriter(new OutputStreamWriter(output, encoding), 4 * 1024, true);
+ } else {
+ vw.recycle(new OutputStreamWriter(output, encoding));
+ }
+ 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();
+ } catch (IOException e) {
+ // do nothing
+ }
+
+ // Clear the VelocityWriter's reference to its internal OutputStreamWriter to allow
+ // the latter to be GC'd while vw is pooled.
+ vw.recycle(null);
+ _writerPool.put(vw);
+ }
+ }
+ }
+
+ /**
+ * This method is called to select the appropriate logic for this request URI.
+ *
+ * @return The logic to be used in generating the response or null if no logic could be
+ * matched.
*/
protected Logic resolveLogic (String path)
{
@@ -488,14 +582,12 @@ public class DispatcherServlet extends VelocityServlet
// nothing interesting to report
} catch (Throwable t) {
- Log.warning("Unable to instantiate logic for application " +
- "[path=" + path + ", lclass=" + lclass + "].");
- Log.logStackTrace(t);
+ log.log(Level.WARNING, "Unable to instantiate logic for application [path=" + path +
+ ", lclass=" + lclass + "].", t);
}
- // if something failed, use a dummy in it's place so that we
- // don't sit around all day freaking out about our inability
- // to instantiate the proper logic class
+ // if something failed, use a dummy in it's place so that we don't sit around all day
+ // freaking out about our inability to instantiate the proper logic class
if (logic == null) {
logic = new DummyLogic();
}
@@ -519,13 +611,20 @@ public class DispatcherServlet extends VelocityServlet
/** Set to true if we're using the {@link SiteResourceLoader}. */
protected boolean _usingSiteLoading;
+ /** Our default content type. */
+ protected String _defaultContentType;
+
+ /** A pool of VelocityWriter instances. */
+ protected static SimplePool _writerPool = new SimplePool(40);
+
+ /** Describes the location of our properties. */
+ protected static final String INIT_PROPS_KEY = "org.apache.velocity.properties";
+
/** This is the key used in the context for error messages. */
protected static final String ERROR_KEY = "error";
- /**
- * This is the key used to store a reference back to the dispatcher
- * servlet in our invocation context.
- */
+ /** This is the key used to store a reference back to the dispatcher servlet in our invocation
+ * context. */
protected static final String APPLICATION_KEY = "%_app_%";
/** The key used to store the translation tool in the context. */
@@ -551,4 +650,10 @@ public class DispatcherServlet extends VelocityServlet
/** The servlet parameter key specifying the default character set. */
protected static final String CHARSET_KEY = "charset";
+
+ /** The default content type for responses. */
+ protected static final String DEFAULT_CONTENT_TYPE = "text/html";
+
+ /** The default encoding for the output stream. */
+ protected static final String DEFAULT_OUTPUT_ENCODING = "ISO-8859-1";
}
diff --git a/src/java/com/samskivert/velocity/ImportDirective.java b/src/java/com/samskivert/velocity/ImportDirective.java
index 059e8f7d..f6fa6c62 100644
--- a/src/java/com/samskivert/velocity/ImportDirective.java
+++ b/src/java/com/samskivert/velocity/ImportDirective.java
@@ -40,10 +40,9 @@ import com.samskivert.servlet.SiteIdentifier;
import com.samskivert.util.StringUtil;
/**
- * Pluggable directive that handles the #import() statement in VTL. Import is
- * like #parse() except that it creates a compound key
- * (siteId:template_path) based on information from the current
- * request when fetching the imported template.
+ * Pluggable directive that handles the #import() statement in VTL. Import is like #parse() except
+ * that it creates a compound key (siteId:template_path) based on information from the
+ * current request when fetching the imported template.
*/
public class ImportDirective extends Directive
{
@@ -73,14 +72,14 @@ public class ImportDirective extends Directive
{
// make sure an argument was supplied to the directive
if (node.getChild(0) == null) {
- rsvc.error("#import() error : null argument");
+ rsvc.getLog().error("#import() error : null argument");
return false;
}
// make sure that argument has a value
Object value = node.getChild(0).value(context);
if (value == null) {
- rsvc.error("#import() error : null argument");
+ rsvc.getLog().error("#import() error : null argument");
return false;
}
@@ -92,9 +91,8 @@ public class ImportDirective extends Directive
int maxlen = rsvc.getInt(
RuntimeConstants.PARSE_DIRECTIVE_MAXDEPTH, 20);
if (templateStack.length >= maxlen) {
- rsvc.error("Max recursion depth reached (" + maxlen + "). " +
- "File stack: " +
- StringUtil.toString(templateStack) + ".");
+ rsvc.getLog().error("Max recursion depth reached (" + maxlen + "). " +
+ "File stack: " + StringUtil.toString(templateStack) + ".");
return false;
}
@@ -120,7 +118,7 @@ public class ImportDirective extends Directive
try {
siteId = ((Integer)siteIdVal).intValue();
} catch (Exception e) {
- rsvc.error("#import() error: No siteId information in context.");
+ rsvc.getLog().error("#import() error: No siteId information in context.");
}
path = siteId + ":" + path;
}
@@ -131,22 +129,19 @@ public class ImportDirective extends Directive
t = rsvc.getTemplate(path, encoding);
} catch (ResourceNotFoundException rnfe) {
- rsvc.error("#import(): cannot find template '" + path +
- "', called from template " +
- context.getCurrentTemplateName() +
- " at (" + getLine() + ", " + getColumn() + ")");
+ rsvc.getLog().error("#import(): cannot find template '" + path +
+ "', called from template " + context.getCurrentTemplateName() +
+ " at (" + getLine() + ", " + getColumn() + ")");
throw rnfe;
} catch (ParseErrorException pee) {
- rsvc.error("#import(): syntax error in #import()-ed template '" +
- path + "', called from template " +
- context.getCurrentTemplateName() +
- " at (" + getLine() + ", " + getColumn() + ")");
+ rsvc.getLog().error("#import(): syntax error in #import()-ed template '" + path +
+ "', called from template " + context.getCurrentTemplateName() +
+ " at (" + getLine() + ", " + getColumn() + ")");
throw pee;
} catch (Exception e) {
- rsvc.error("#import(): Error [path=" + path +
- ", error=" + e + "].");
+ rsvc.getLog().error("#import(): Error [path=" + path + ", error=" + e + "].");
return false;
}
@@ -156,7 +151,7 @@ public class ImportDirective extends Directive
((SimpleNode)t.getData()).render(context, writer);
} catch (Throwable th) {
- rsvc.error("Exception rendering #import(" + path + "): " + th);
+ rsvc.getLog().error("Exception rendering #import(" + path + "): " + th);
// we want to pass method invocation exceptions through
if (th instanceof MethodInvocationException) {
throw (MethodInvocationException)th;
diff --git a/src/java/com/samskivert/velocity/ServletContextLogger.java b/src/java/com/samskivert/velocity/ServletContextLogger.java
index 946c7908..5b474ec7 100644
--- a/src/java/com/samskivert/velocity/ServletContextLogger.java
+++ b/src/java/com/samskivert/velocity/ServletContextLogger.java
@@ -23,12 +23,12 @@ package com.samskivert.velocity;
import javax.servlet.ServletContext;
import org.apache.velocity.runtime.RuntimeServices;
-import org.apache.velocity.runtime.log.LogSystem;
+import org.apache.velocity.runtime.log.LogChute;
/**
* Routes Velocity log messages to the servlet context.
*/
-public class ServletContextLogger implements LogSystem
+public class ServletContextLogger implements LogChute
{
/**
* Constructs a servlet context logger that will obtain its servlet
@@ -48,22 +48,21 @@ public class ServletContextLogger implements LogSystem
_sctx = sctx;
}
- // documentation inherited
+ // from interface LogChute
public void init (RuntimeServices rsvc)
{
// if we weren't constructed with a servlet context, try to obtain
// one via the application context
if (_sctx == null) {
// first look for the servlet context directly
- _sctx = (ServletContext)
- rsvc.getApplicationAttribute("ServletContext");
+ _sctx = (ServletContext)rsvc.getApplicationAttribute("ServletContext");
}
// if that didn't work, look for an application
if (_sctx == null) {
// first look for an application
- Application app = (Application)rsvc.getApplicationAttribute(
- Application.VELOCITY_ATTR_KEY);
+ Application app = (Application)
+ rsvc.getApplicationAttribute(Application.VELOCITY_ATTR_KEY);
if (app != null) {
_sctx = app.getServletContext();
}
@@ -71,22 +70,35 @@ public class ServletContextLogger implements LogSystem
// if we still don't have one, complain
if (_sctx == null) {
- rsvc.warn("ServletContextLogger: servlet context was not " +
- "supplied. A user of the servlet context logger must " +
- "call Velocity.setApplicationAttribute(" +
- "\"ServletContext\", getServletContext()).");
+ rsvc.getLog().warn("ServletContextLogger: servlet context was not supplied. A user " +
+ "of the servlet context logger must call " +
+ "Velocity.setApplicationAttribute(\"ServletContext\", " +
+ "getServletContext()).");
}
}
- // documentation inherited
- public void logVelocityMessage (int level, String message)
+ // from interface LogChute
+ public void log (int level, String message)
{
- // log only warning or above for now
- if (level >= LogSystem.WARN_ID) {
+ if (isLevelEnabled(level)) {
_sctx.log(message);
}
}
+ // from interface LogChute
+ public void log (int level, String message, Throwable t)
+ {
+ if (isLevelEnabled(level)) {
+ _sctx.log(message, t);
+ }
+ }
+
+ // from interface LogChute
+ public boolean isLevelEnabled (int level)
+ {
+ return (level >= WARN_ID);
+ }
+
/** A reference to our servlet context. */
protected ServletContext _sctx;
}
diff --git a/src/java/com/samskivert/velocity/ServletContextResourceLoader.java b/src/java/com/samskivert/velocity/ServletContextResourceLoader.java
index 87466a0d..cbb8bdfc 100644
--- a/src/java/com/samskivert/velocity/ServletContextResourceLoader.java
+++ b/src/java/com/samskivert/velocity/ServletContextResourceLoader.java
@@ -29,8 +29,7 @@ import org.apache.velocity.runtime.resource.Resource;
import org.apache.velocity.runtime.resource.loader.ResourceLoader;
/**
- * A Velocity resource loader that loads resources from the servlet
- * context.
+ * A Velocity resource loader that loads resources from the servlet context.
*
* @see ServletContext#getResource
* @see ServletContext#getResourceAsStream
@@ -38,17 +37,16 @@ import org.apache.velocity.runtime.resource.loader.ResourceLoader;
public class ServletContextResourceLoader extends ResourceLoader
{
/**
- * When used with the default Velocity resource manager, we are
- * constructed with our zero-argument constructor and later
- * initialized via {@link #init}.
+ * When used with the default Velocity resource manager, we are constructed with our
+ * zero-argument constructor and later initialized via {@link #init}.
*/
public ServletContextResourceLoader ()
{
}
/**
- * When used with the {@link SiteResourceManager} we are constructed
- * with our servlet context reference and not later initialized.
+ * When used with the {@link SiteResourceManager} we are constructed with our servlet context
+ * reference and not later initialized.
*/
public ServletContextResourceLoader (ServletContext sctx)
{
@@ -60,22 +58,14 @@ public class ServletContextResourceLoader extends ResourceLoader
*/
public void init (ExtendedProperties config)
{
- // there seems to be a tradition of logging this stuff; surely we
- // don't want to buck tradition, do we?
- rsvc.info("ServletContextResourceLoader: initialization starting.");
-
- // the web framework was kind enough to slip this into the runtime
- // instance when it started up
+ // the web framework was kind enough to slip this into the runtime when it started up
_sctx = (ServletContext)rsvc.getApplicationAttribute("ServletContext");
if (_sctx == null) {
- rsvc.warn("ServletContextResourceLoader: servlet context " +
- "was not supplied as application context. A " +
- "user of the servlet context resource loader " +
- "must call Velocity.setApplicationAttribute(" +
- "\"ServletContext\", getServletContext()).");
+ rsvc.getLog().warn("ServletContextResourceLoader: servlet context was not supplied " +
+ "as application context. A user of the servlet context resource " +
+ "loader must call Velocity.setApplicationAttribute(" +
+ "\"ServletContext\", getServletContext()).");
}
-
- rsvc.info("ServletContextResourceLoader : initialization complete.");
}
/**
diff --git a/src/java/com/samskivert/velocity/ServletContextResourceManager.java b/src/java/com/samskivert/velocity/ServletContextResourceManager.java
index e991d030..46924e29 100644
--- a/src/java/com/samskivert/velocity/ServletContextResourceManager.java
+++ b/src/java/com/samskivert/velocity/ServletContextResourceManager.java
@@ -31,8 +31,7 @@ import org.apache.velocity.runtime.resource.ResourceManagerImpl;
import org.apache.velocity.runtime.resource.loader.ResourceLoader;
/**
- * A resource manager implementation for Velocity that loads resources
- * from the servlet context.
+ * A resource manager implementation for Velocity that loads resources from the servlet context.
*/
public class ServletContextResourceManager extends ResourceManagerImpl
{
@@ -40,37 +39,31 @@ public class ServletContextResourceManager extends ResourceManagerImpl
throws Exception
{
super.initialize(rsvc);
- rsvc.info("SCRM initializing.");
+ rsvc.getLog().info("SCRM initializing.");
- // the web framework was kind enough to slip this into the runtime
- // instance when it started up
- Application app = (Application)rsvc.getApplicationAttribute(
- Application.VELOCITY_ATTR_KEY);
+ // the web framework was kind enough to slip this into the runtime when it started up
+ Application app = (Application)rsvc.getApplicationAttribute(Application.VELOCITY_ATTR_KEY);
if (app == null) {
- rsvc.warn("SCRM: No application was initialized. A user of the " +
- "servlet context resource manager must ensure that " +
- "an application is instantiated and initialized.");
+ rsvc.getLog().warn("SCRM: No application was initialized. A user of the " +
+ "servlet context resource manager must ensure that " +
+ "an application is instantiated and initialized.");
}
// create our resource loader
- _contextLoader = new ServletContextResourceLoader(
- app.getServletContext());
+ _contextLoader = new ServletContextResourceLoader(app.getServletContext());
- // for now, turn caching on with the expectation that new
- // resources of any sort will result in the entire web application
- // being reloaded and clearing out the cache
+ // for now, turn caching on with the expectation that new resources of any sort will result
+ // in the entire web application being reloaded and clearing out the cache
_contextLoader.setCachingOn(true);
- rsvc.info("SCRM initialization complete.");
+ rsvc.getLog().info("SCRM initialization complete.");
}
- protected Resource loadResource(
- String resourceName, int resourceType, String encoding)
+ protected Resource loadResource(String resourceName, int resourceType, String encoding)
throws ResourceNotFoundException, ParseErrorException, Exception
{
// create a blank new resource
- Resource resource =
- ResourceFactory.getResource(resourceName, resourceType);
+ Resource resource = ResourceFactory.getResource(resourceName, resourceType);
resource.setRuntimeServices(rsvc);
resource.setName(resourceName);
resource.setEncoding(encoding);
@@ -78,8 +71,7 @@ public class ServletContextResourceManager extends ResourceManagerImpl
resource.setResourceLoader(_contextLoader);
resource.process();
resource.setLastModified(_contextLoader.getLastModified(resource));
- resource.setModificationCheckInterval(
- _contextLoader.getModificationCheckInterval());
+ resource.setModificationCheckInterval(_contextLoader.getModificationCheckInterval());
resource.touch();
return resource;
diff --git a/src/java/com/samskivert/velocity/SiteResourceManager.java b/src/java/com/samskivert/velocity/SiteResourceManager.java
index ab090669..03a9cea4 100644
--- a/src/java/com/samskivert/velocity/SiteResourceManager.java
+++ b/src/java/com/samskivert/velocity/SiteResourceManager.java
@@ -30,13 +30,15 @@ import org.apache.velocity.runtime.resource.ResourceFactory;
import org.apache.velocity.runtime.resource.ResourceManagerImpl;
import org.apache.velocity.runtime.resource.loader.ResourceLoader;
+import com.samskivert.Log;
+
import com.samskivert.servlet.SiteIdentifier;
import com.samskivert.servlet.SiteResourceLoader;
/**
- * A resource manager implementation for Velocity that first loads site
- * specific resources (via the {@link SiteJarResourceLoader}), but falls back
- * to default resources if no site-specific resource loader is available.
+ * A resource manager implementation for Velocity that first loads site specific resources (via the
+ * {@link SiteJarResourceLoader}), but falls back to default resources if no site-specific resource
+ * loader is available.
*/
public class SiteResourceManager extends ResourceManagerImpl
{
@@ -44,16 +46,15 @@ public class SiteResourceManager extends ResourceManagerImpl
throws Exception
{
super.initialize(rsvc);
- rsvc.info("SiteResourceManager initializing.");
+ Log.log.info("SiteResourceManager initializing.");
- // the web framework was kind enough to slip this into the runtime
- // instance when it started up
+ // the web framework was kind enough to slip this into the runtime when it started up
Application app = (Application)rsvc.getApplicationAttribute(
Application.VELOCITY_ATTR_KEY);
if (app == null) {
- rsvc.warn("SiteResourceManager: No application was initialized. " +
- "A user of the site resource manager must ensure that " +
- "an application is instantiated and initialized.");
+ Log.log.warning("SiteResourceManager: No application was initialized. " +
+ "A user of the site resource manager must ensure that " +
+ "an application is instantiated and initialized.");
}
// get handles on the good stuff
@@ -63,33 +64,30 @@ public class SiteResourceManager extends ResourceManagerImpl
// make sure the app has a site resource loader
SiteResourceLoader loader = app.getSiteResourceLoader();
if (loader == null) {
- rsvc.warn("SiteResourceManager: application must be " +
- "configured with a site-specific resource loader " +
- "that we can use to fetch site-specific resources.");
+ Log.log.warning("SiteResourceManager: application must be " +
+ "configured with a site-specific resource loader " +
+ "that we can use to fetch site-specific resources.");
}
// create our resource loaders
_siteLoader = new SiteJarResourceLoader(loader);
_contextLoader = new ServletContextResourceLoader(_sctx);
- // for now, turn caching on with the expectation that new
- // resources of any sort will result in the entire web application
- // being reloaded and clearing out the cache
+ // for now, turn caching on with the expectation that new resources of any sort will result
+ // in the entire web application being reloaded and clearing out the cache
_siteLoader.setCachingOn(true);
_contextLoader.setCachingOn(true);
- rsvc.info("SiteResourceManager initialization complete.");
+ Log.log.info("SiteResourceManager initialization complete.");
}
- protected Resource loadResource(
- String resourceName, int resourceType, String encoding)
+ protected Resource loadResource(String resourceName, int resourceType, String encoding)
throws ResourceNotFoundException, ParseErrorException, Exception
{
SiteKey skey = new SiteKey(resourceName);
// create a blank new resource
- Resource resource =
- ResourceFactory.getResource(skey.path, resourceType);
+ Resource resource = ResourceFactory.getResource(skey.path, resourceType);
resource.setRuntimeServices(rsvc);
resource.setEncoding(encoding);
@@ -101,8 +99,7 @@ public class SiteResourceManager extends ResourceManagerImpl
// nothing to worry about here
}
- // then try the servlet context loader if we didn't find a
- // site-specific resource
+ // then try the servlet context loader if we didn't find a site-specific resource
if (resource.getData() == null) {
resource.setName(skey.path);
resolveResource(resource, _contextLoader);
@@ -117,8 +114,7 @@ public class SiteResourceManager extends ResourceManagerImpl
resource.setResourceLoader(loader);
resource.process();
resource.setLastModified(loader.getLastModified(resource));
- resource.setModificationCheckInterval(
- loader.getModificationCheckInterval());
+ resource.setModificationCheckInterval(loader.getModificationCheckInterval());
resource.touch();
}