📄 velocimacrofactory.java
字号:
* maybe we should throw an exception, maybe just tell
* the caller like this...
*
* I hate this : maybe exceptions are in order here...
*/
if (name == null || macroBody == null || argArray == null ||
sourceTemplate == null)
{
log.warn("VM addition rejected : programmer error : arg null");
return false;
}
/*
* see if the current ruleset allows this addition
*/
if (!canAddVelocimacro(name, sourceTemplate))
{
return false;
}
/*
* seems like all is good. Lets do it.
*/
synchronized(this)
{
vmManager.addVM(name, macroBody, argArray, sourceTemplate);
}
/*
* Report addition of the new Velocimacro.
*/
StringBuffer msg = new StringBuffer("added ");
Macro.macroToString(msg, argArray);
msg.append(" : source = ").append(sourceTemplate);
log.info(msg.toString());
return true;
}
/**
* determines if a given macro/namespace (name, source) combo is allowed
* to be added
*
* @param name Name of VM to add
* @param sourceTemplate Source template that contains the defintion of the VM
* @return true if it is allowed to be added, false otherwise
*/
private synchronized boolean canAddVelocimacro(String name, String sourceTemplate)
{
/*
* short circuit and do it if autoloader is on, and the
* template is one of the library templates
*/
if (getAutoload() && (macroLibVec != null))
{
/*
* see if this is a library template
*/
for(int i = 0; i < macroLibVec.size(); i++)
{
String lib = (String) macroLibVec.elementAt(i);
if (lib.equals(sourceTemplate))
{
return true;
}
}
}
/*
* maybe the rules should be in manager? I dunno. It's to manage
* the namespace issues first, are we allowed to add VMs at all?
* This trumps all.
*/
if (!addNewAllowed)
{
log.warn("VM addition rejected : "+name+" : inline VMs not allowed.");
return false;
}
/*
* are they local in scope? Then it is ok to add.
*/
if (!templateLocal)
{
/*
* otherwise, if we have it already in global namespace, and they can't replace
* since local templates are not allowed, the global namespace is implied.
* remember, we don't know anything about namespace managment here, so lets
* note do anything fancy like trying to give it the global namespace here
*
* so if we have it, and we aren't allowed to replace, bail
*/
if (isVelocimacro(name, sourceTemplate) && !replaceAllowed)
{
log.warn("VM addition rejected : "+name+" : inline not allowed to replace existing VM");
return false;
}
}
return true;
}
/**
* Tells the world if a given directive string is a Velocimacro
* @param vm Name of the Macro.
* @param sourceTemplate Source template from which the macro should be loaded.
* @return True if the given name is a macro.
*/
public boolean isVelocimacro(String vm , String sourceTemplate)
{
synchronized(this)
{
/*
* first we check the locals to see if we have
* a local definition for this template
*/
if (vmManager.get(vm, sourceTemplate) != null)
return true;
}
return false;
}
/**
* actual factory : creates a Directive that will
* behave correctly wrt getting the framework to
* dig out the correct # of args
* @param vmName Name of the Macro.
* @param sourceTemplate Source template from which the macro should be loaded.
* @return A directive representing the Macro.
*/
public Directive getVelocimacro(String vmName, String sourceTemplate)
{
VelocimacroProxy vp = null;
synchronized(this)
{
/*
* don't ask - do
*/
vp = vmManager.get(vmName, sourceTemplate);
/*
* if this exists, and autoload is on, we need to check
* where this VM came from
*/
if (vp != null && getAutoload())
{
/*
* see if this VM came from a library. Need to pass sourceTemplate
* in the event namespaces are set, as it could be masked by local
*/
String lib = vmManager.getLibraryName(vmName, sourceTemplate);
if (lib != null)
{
try
{
/*
* get the template from our map
*/
Twonk tw = (Twonk) libModMap.get(lib);
if (tw != null)
{
Template template = tw.template;
/*
* now, compare the last modified time of the resource
* with the last modified time of the template
* if the file has changed, then reload. Otherwise, we should
* be ok.
*/
long tt = tw.modificationTime;
long ft = template.getResourceLoader().getLastModified(template);
if (ft > tt)
{
log.debug("auto-reloading VMs from VM library : "+lib);
/*
* when there are VMs in a library that invoke each other,
* there are calls into getVelocimacro() from the init()
* process of the VM directive. To stop the infinite loop
* we save the current time reported by the resource loader
* and then be honest when the reload is complete
*/
tw.modificationTime = ft;
template = rsvc.getTemplate(lib);
/*
* and now we be honest
*/
tw.template = template;
tw.modificationTime = template.getLastModified();
/*
* note that we don't need to put this twonk back
* into the map, as we can just use the same reference
* and this block is synchronized
*/
}
}
}
catch (Exception e)
{
log.error(true, "Velocimacro : Error using VM library : "+lib, e);
}
/*
* and get again
*/
vp = vmManager.get(vmName, sourceTemplate);
}
}
}
return vp;
}
/**
* tells the vmManager to dump the specified namespace
* @param namespace Namespace to dump.
* @return True if namespace has been dumped successfully.
*/
public boolean dumpVMNamespace(String namespace)
{
return vmManager.dumpNamespace(namespace);
}
/**
* sets permission to have VMs local in scope to their declaring template
* note that this is really taken care of in the VMManager class, but
* we need it here for gating purposes in addVM
* eventually, I will slide this all into the manager, maybe.
*/
private void setTemplateLocalInline(boolean b)
{
templateLocal = b;
}
private boolean getTemplateLocalInline()
{
return templateLocal;
}
/**
* sets the permission to add new macros
*/
private boolean setAddMacroPermission(final boolean addNewAllowed)
{
boolean b = this.addNewAllowed;
this.addNewAllowed = addNewAllowed;
return b;
}
/**
* sets the permission for allowing addMacro() calls to
* replace existing VM's
*/
private boolean setReplacementPermission(boolean arg)
{
boolean b = replaceAllowed;
replaceAllowed = arg;
return b;
}
/**
* set the switch for automatic reloading of
* global library-based VMs
*/
private void setAutoload(boolean b)
{
autoReloadLibrary = b;
}
/**
* get the switch for automatic reloading of
* global library-based VMs
*/
private boolean getAutoload()
{
return autoReloadLibrary;
}
/**
* small container class to hold the tuple
* of a template and modification time.
* We keep the modification time so we can
* 'override' it on a reload to prevent
* recursive reload due to inter-calling
* VMs in a library
*/
private static class Twonk
{
/** Template kept in this container. */
public Template template;
/** modification time of the template. */
public long modificationTime;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -