VelocityManagerpublic class VelocityManager extends Object Manages the environment for Velocity result types |
Fields Summary |
---|
private static final Log | log | public static final String | STRUTS | private com.opensymphony.xwork2.ObjectFactory | objectFactory | public static final String | PARENTthe parent JSP tag | public static final String | TAGthe current JSP tag | private org.apache.velocity.app.VelocityEngine | velocityEngine | protected org.apache.velocity.tools.view.ToolboxManager | toolboxManagerA reference to the toolbox manager. | private String | toolBoxLocation | private String[] | chainedContextNamesNames of contexts that will be chained on every request | private Properties | velocityProperties | private String | customConfigFile | private List | tagLibraries |
Constructors Summary |
---|
public VelocityManager()
|
Methods Summary |
---|
private void | addDirective(java.lang.StringBuffer sb, java.lang.Class clazz)
sb.append(clazz.getName()).append(",");
| private void | applyDefaultConfiguration(javax.servlet.ServletContext context, java.util.Properties p)once we've loaded up the user defined configurations, we will want to apply Struts specification configurations.
- if Velocity.RESOURCE_LOADER has not been defined, then we will use the defaults which is a joined file,
class loader for unpackaed wars and a straight class loader otherwise
- we need to define the various Struts custom user directives such as #param, #tag, and #bodytag
// ensure that caching isn't overly aggressive
/**
* Load a default resource loader definition if there isn't one present.
* Ben Hall (22/08/2003)
*/
if (p.getProperty(Velocity.RESOURCE_LOADER) == null) {
p.setProperty(Velocity.RESOURCE_LOADER, "strutsfile, strutsclass");
}
/**
* If there's a "real" path add it for the strutsfile resource loader.
* If there's no real path and they haven't configured a loader then we change
* resource loader property to just use the strutsclass loader
* Ben Hall (22/08/2003)
*/
if (context.getRealPath("") != null) {
p.setProperty("strutsfile.resource.loader.description", "Velocity File Resource Loader");
p.setProperty("strutsfile.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
p.setProperty("strutsfile.resource.loader.path", context.getRealPath(""));
p.setProperty("strutsfile.resource.loader.modificationCheckInterval", "2");
p.setProperty("strutsfile.resource.loader.cache", "true");
} else {
// remove strutsfile from resource loader property
String prop = p.getProperty(Velocity.RESOURCE_LOADER);
if (prop.indexOf("strutsfile,") != -1) {
prop = replace(prop, "strutsfile,", "");
} else if (prop.indexOf(", strutsfile") != -1) {
prop = replace(prop, ", strutsfile", "");
} else if (prop.indexOf("strutsfile") != -1) {
prop = replace(prop, "strutsfile", "");
}
p.setProperty(Velocity.RESOURCE_LOADER, prop);
}
/**
* Refactored the Velocity templates for the Struts taglib into the classpath from the web path. This will
* enable Struts projects to have access to the templates by simply including the Struts jar file.
* Unfortunately, there does not appear to be a macro for the class loader keywords
* Matt Ho - Mon Mar 17 00:21:46 PST 2003
*/
p.setProperty("strutsclass.resource.loader.description", "Velocity Classpath Resource Loader");
p.setProperty("strutsclass.resource.loader.class", "org.apache.struts2.views.velocity.StrutsResourceLoader");
p.setProperty("strutsclass.resource.loader.modificationCheckInterval", "2");
p.setProperty("strutsclass.resource.loader.cache", "true");
// components
StringBuffer sb = new StringBuffer();
for (TagLibrary tagLibrary : tagLibraries) {
List<Class> directives = tagLibrary.getVelocityDirectiveClasses();
for (Class directive : directives) {
addDirective(sb, directive);
}
}
String directives = sb.toString();
String userdirective = p.getProperty("userdirective");
if ((userdirective == null) || userdirective.trim().equals("")) {
userdirective = directives;
} else {
userdirective = userdirective.trim() + "," + directives;
}
p.setProperty("userdirective", userdirective);
| public org.apache.velocity.context.Context | createContext(com.opensymphony.xwork2.util.ValueStack stack, javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse res)This method is responsible for creating the standard VelocityContext used by all WW2 velocity views. The
following context parameters are defined:
- request - the current HttpServletRequest
- response - the current HttpServletResponse
- stack - the current {@link ValueStack}
- ognl - an {@link OgnlTool}
- struts - an instance of {@link org.apache.struts2.util.StrutsUtil}
- action - the current Struts action
VelocityContext[] chainedContexts = prepareChainedContexts(req, res, stack.getContext());
StrutsVelocityContext context = new StrutsVelocityContext(chainedContexts, stack);
Map standardMap = ContextUtil.getStandardContext(stack, req, res);
for (Iterator iterator = standardMap.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
context.put((String) entry.getKey(), entry.getValue());
}
context.put(STRUTS, new VelocityStrutsUtil(velocityEngine, context, stack, req, res));
ServletContext ctx = null;
try {
ctx = ServletActionContext.getServletContext();
} catch (NullPointerException npe) {
// in case this was used outside the lifecycle of struts servlet
log.debug("internal toolbox context ignored");
}
if (toolboxManager != null && ctx != null) {
ChainedContext chained = new ChainedContext(context, req, res, ctx);
chained.setToolbox(toolboxManager.getToolboxContext(chained));
return chained;
} else {
return context;
}
| public org.apache.velocity.app.VelocityEngine | getVelocityEngine()
return velocityEngine;
| public java.util.Properties | getVelocityProperties()
return velocityProperties;
| public synchronized void | init(javax.servlet.ServletContext context)initializes the VelocityManager. this should be called during the initialization process, say by
ServletDispatcher. this may be called multiple times safely although calls beyond the first won't do anything
if (velocityEngine == null) {
velocityEngine = newVelocityEngine(context);
}
this.initToolbox(context);
| protected void | initToolbox(javax.servlet.ServletContext context)Initializes the ServletToolboxManager for this servlet's
toolbox (if any).
/* if we have a toolbox, get a manager for it */
if (toolBoxLocation != null) {
toolboxManager = ServletToolboxManager.getInstance(context, toolBoxLocation);
} else {
Velocity.info("VelocityViewServlet: No toolbox entry in configuration.");
}
| public java.util.Properties | loadConfiguration(javax.servlet.ServletContext context)load optional velocity properties using the following loading strategy
- relative to the servlet context path
- relative to the WEB-INF directory
- on the classpath
if (context == null) {
String gripe = "Error attempting to create a loadConfiguration from a null ServletContext!";
log.error(gripe);
throw new IllegalArgumentException(gripe);
}
Properties properties = new Properties();
// now apply our systemic defaults, then allow user to override
applyDefaultConfiguration(context, properties);
String defaultUserDirective = properties.getProperty("userdirective");
/**
* if the user has specified an external velocity configuration file, we'll want to search for it in the
* following order
*
* 1. relative to the context path
* 2. relative to /WEB-INF
* 3. in the class path
*/
String configfile;
if (customConfigFile != null) {
configfile = customConfigFile;
} else {
configfile = "velocity.properties";
}
configfile = configfile.trim();
InputStream in = null;
String resourceLocation = null;
try {
if (context.getRealPath(configfile) != null) {
// 1. relative to context path, i.e. /velocity.properties
String filename = context.getRealPath(configfile);
if (filename != null) {
File file = new File(filename);
if (file.isFile()) {
resourceLocation = file.getCanonicalPath() + " from file system";
in = new FileInputStream(file);
}
// 2. if nothing was found relative to the context path, search relative to the WEB-INF directory
if (in == null) {
file = new File(context.getRealPath("/WEB-INF/" + configfile));
if (file.isFile()) {
resourceLocation = file.getCanonicalPath() + " from file system";
in = new FileInputStream(file);
}
}
}
}
// 3. finally, if there's no physical file, how about something in our classpath
if (in == null) {
in = VelocityManager.class.getClassLoader().getResourceAsStream(configfile);
if (in != null) {
resourceLocation = configfile + " from classloader";
}
}
// if we've got something, load 'er up
if (in != null) {
log.info("Initializing velocity using " + resourceLocation);
properties.load(in);
}
} catch (IOException e) {
log.warn("Unable to load velocity configuration " + resourceLocation, e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
// overide with programmatically set properties
if (this.velocityProperties != null) {
Iterator keys = this.velocityProperties.keySet().iterator();
while (keys.hasNext()) {
String key = (String) keys.next();
properties.setProperty(key, this.velocityProperties.getProperty(key));
}
}
String userdirective = properties.getProperty("userdirective");
if ((userdirective == null) || userdirective.trim().equals("")) {
userdirective = defaultUserDirective;
} else {
userdirective = userdirective.trim() + "," + defaultUserDirective;
}
properties.setProperty("userdirective", userdirective);
// for debugging purposes, allows users to dump out the properties that have been configured
if (log.isDebugEnabled()) {
log.debug("Initializing Velocity with the following properties ...");
for (Iterator iter = properties.keySet().iterator();
iter.hasNext();) {
String key = (String) iter.next();
String value = properties.getProperty(key);
if (log.isDebugEnabled()) {
log.debug(" '" + key + "' = '" + value + "'");
}
}
}
return properties;
| protected org.apache.velocity.app.VelocityEngine | newVelocityEngine(javax.servlet.ServletContext context)
Instantiates a new VelocityEngine.
The following is the default Velocity configuration
resource.loader = file, class
file.resource.loader.path = real path of webapp
class.resource.loader.description = Velocity Classpath Resource Loader
class.resource.loader.class = org.apache.struts2.views.velocity.StrutsResourceLoader
this default configuration can be overridden by specifying a struts.velocity.configfile property in the
struts.properties file. the specified config file will be searched for in the following order:
- relative to the servlet context path
- relative to the WEB-INF directory
- on the classpath
if (context == null) {
String gripe = "Error attempting to create a new VelocityEngine from a null ServletContext!";
log.error(gripe);
throw new IllegalArgumentException(gripe);
}
Properties p = loadConfiguration(context);
VelocityEngine velocityEngine = new VelocityEngine();
// Set the velocity attribute for the servlet context
// if this is not set the webapp loader WILL NOT WORK
velocityEngine.setApplicationAttribute(ServletContext.class.getName(),
context);
try {
velocityEngine.init(p);
} catch (Exception e) {
String gripe = "Unable to instantiate VelocityEngine!";
throw new StrutsException(gripe, e);
}
return velocityEngine;
| protected org.apache.velocity.VelocityContext[] | prepareChainedContexts(javax.servlet.http.HttpServletRequest servletRequest, javax.servlet.http.HttpServletResponse servletResponse, java.util.Map extraContext)constructs contexts for chaining on this request. This method does not
perform any initialization of the contexts. All that must be done in the
context itself.
if (this.chainedContextNames == null) {
return null;
}
List contextList = new ArrayList();
for (int i = 0; i < chainedContextNames.length; i++) {
String className = chainedContextNames[i];
try {
VelocityContext velocityContext = (VelocityContext) objectFactory.buildBean(className, null);
contextList.add(velocityContext);
} catch (Exception e) {
log.warn("Warning. " + e.getClass().getName() + " caught while attempting to instantiate a chained VelocityContext, " + className + " -- skipping");
}
}
if (contextList.size() > 0) {
VelocityContext[] extraContexts = new VelocityContext[contextList.size()];
contextList.toArray(extraContexts);
return extraContexts;
} else {
return null;
}
| private static final java.lang.String | replace(java.lang.String string, java.lang.String oldString, java.lang.String newString)
if (string == null) {
return null;
}
// If the newString is null, just return the string since there's nothing to replace.
if (newString == null) {
return string;
}
int i = 0;
// Make sure that oldString appears at least once before doing any processing.
if ((i = string.indexOf(oldString, i)) >= 0) {
// Use char []'s, as they are more efficient to deal with.
char[] string2 = string.toCharArray();
char[] newString2 = newString.toCharArray();
int oLength = oldString.length();
StringBuffer buf = new StringBuffer(string2.length);
buf.append(string2, 0, i).append(newString2);
i += oLength;
int j = i;
// Replace all remaining instances of oldString with newString.
while ((i = string.indexOf(oldString, i)) > 0) {
buf.append(string2, j, i - j).append(newString2);
i += oLength;
j = i;
}
buf.append(string2, j, string2.length - j);
return buf.toString();
}
return string;
| public void | setChainedContexts(java.lang.String contexts)allow users to specify via the struts.properties file a set of additional VelocityContexts to chain to the
the StrutsVelocityContext. The intent is to allow these contexts to store helper objects that the ui
developer may want access to. Examples of reasonable VelocityContexts would be an IoCVelocityContext, a
SpringReferenceVelocityContext, and a ToolboxVelocityContext
// we expect contexts to be a comma separated list of classnames
StringTokenizer st = new StringTokenizer(contexts, ",");
List contextList = new ArrayList();
while (st.hasMoreTokens()) {
String classname = st.nextToken();
contextList.add(classname);
}
if (contextList.size() > 0) {
String[] chainedContexts = new String[contextList.size()];
contextList.toArray(chainedContexts);
this.chainedContextNames = chainedContexts;
}
| public void | setContainer(com.opensymphony.xwork2.inject.Container container)
List<TagLibrary> list = new ArrayList<TagLibrary>();
Set<String> prefixes = container.getInstanceNames(TagLibrary.class);
for (String prefix : prefixes) {
list.add(container.getInstance(TagLibrary.class, prefix));
}
this.tagLibraries = Collections.unmodifiableList(list);
| public void | setCustomConfigFile(java.lang.String val)
this.customConfigFile = val;
| public void | setObjectFactory(com.opensymphony.xwork2.ObjectFactory fac)
this.objectFactory = fac;
| public void | setToolBoxLocation(java.lang.String toolboxLocation)
this.toolBoxLocation = toolboxLocation;
| public void | setVelocityProperties(java.util.Properties velocityProperties)
this.velocityProperties = velocityProperties;
|
|