📄 velocimacrofactory.java
字号:
package org.apache.velocity.runtime;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.runtime.directive.Directive;
import org.apache.velocity.runtime.directive.Macro;
import org.apache.velocity.runtime.directive.VelocimacroProxy;
import org.apache.velocity.runtime.log.LogDisplayWrapper;
/**
* VelocimacroFactory.java
*
* manages the set of VMs in a running Velocity engine.
*
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
* @version $Id: VelocimacroFactory.java 469919 2006-11-01 14:35:46Z henning $
*/
public class VelocimacroFactory
{
/**
* runtime services for this instance
*/
private final RuntimeServices rsvc;
/**
* the log for this instance
*/
private final LogDisplayWrapper log;
/**
* VMManager : deal with namespace management
* and actually keeps all the VM definitions
*/
private VelocimacroManager vmManager = null;
/**
* determines if replacement of global VMs are allowed
* controlled by VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL
*/
private boolean replaceAllowed = false;
/**
* controls if new VMs can be added. Set by
* VM_PERM_ALLOW_INLINE Note the assumption that only
* through inline defs can this happen.
* additions through autoloaded VMs is allowed
*/
private boolean addNewAllowed = true;
/**
* sets if template-local namespace in used
*/
private boolean templateLocal = false;
/**
* determines if the libraries are auto-loaded
* when they change
*/
private boolean autoReloadLibrary = false;
/**
* vector of the library names
*/
private Vector macroLibVec = null;
/**
* map of the library Template objects
* used for reload determination
*/
private Map libModMap;
/**
* C'tor for the VelociMacro factory.
*
* @param rsvc Reference to a runtime services object.
*/
public VelocimacroFactory(final RuntimeServices rsvc)
{
this.rsvc = rsvc;
this.log = new LogDisplayWrapper(rsvc.getLog(), "Velocimacro : ",
rsvc.getBoolean(RuntimeConstants.VM_MESSAGES_ON, true));
/*
* we always access in a synchronized(), so we
* can use an unsynchronized hashmap
*/
libModMap = new HashMap();
vmManager = new VelocimacroManager(rsvc);
}
/**
* initialize the factory - setup all permissions
* load all global libraries.
*/
public void initVelocimacro()
{
/*
* maybe I'm just paranoid...
*/
synchronized(this)
{
log.trace("initialization starting.");
/*
* allow replacements while we add the libraries, if exist
*/
setReplacementPermission(true);
/*
* add all library macros to the global namespace
*/
vmManager.setNamespaceUsage(false);
/*
* now, if there is a global or local libraries specified, use them.
* All we have to do is get the template. The template will be parsed;
* VM's are added during the parse phase
*/
Object libfiles = rsvc.getProperty(RuntimeConstants.VM_LIBRARY);
if (libfiles == null)
{
log.debug("\"" + RuntimeConstants.VM_LIBRARY +
"\" is not set. Trying default library: " +
RuntimeConstants.VM_LIBRARY_DEFAULT);
// try the default library.
if (rsvc.getLoaderNameForResource(RuntimeConstants.VM_LIBRARY_DEFAULT) != null)
{
libfiles = RuntimeConstants.VM_LIBRARY_DEFAULT;
}
else
{
log.debug("Default library not found.");
}
}
if(libfiles != null)
{
if (libfiles instanceof Vector)
{
macroLibVec = (Vector) libfiles;
}
else if (libfiles instanceof String)
{
macroLibVec = new Vector();
macroLibVec.addElement(libfiles);
}
for(int i = 0; i < macroLibVec.size(); i++)
{
String lib = (String) macroLibVec.elementAt(i);
/*
* only if it's a non-empty string do we bother
*/
if (StringUtils.isNotEmpty(lib))
{
/*
* let the VMManager know that the following is coming
* from libraries - need to know for auto-load
*/
vmManager.setRegisterFromLib(true);
log.debug("adding VMs from VM library : " + lib);
try
{
Template template = rsvc.getTemplate(lib);
/*
* save the template. This depends on the assumption
* that the Template object won't change - currently
* this is how the Resource manager works
*/
Twonk twonk = new Twonk();
twonk.template = template;
twonk.modificationTime = template.getLastModified();
libModMap.put(lib, twonk);
}
catch (Exception e)
{
log.error(true, "Velocimacro : Error using VM library : " + lib, e);
}
log.trace("VM library registration complete.");
vmManager.setRegisterFromLib(false);
}
}
}
/*
* now, the permissions
*/
/*
* allowinline : anything after this will be an inline macro, I think
* there is the question if a #include is an inline, and I think so
*
* default = true
*/
setAddMacroPermission(true);
if (!rsvc.getBoolean( RuntimeConstants.VM_PERM_ALLOW_INLINE, true))
{
setAddMacroPermission(false);
log.info("allowInline = false : VMs can NOT be defined inline in templates");
}
else
{
log.debug("allowInline = true : VMs can be defined inline in templates");
}
/*
* allowInlineToReplaceGlobal : allows an inline VM , if allowed at all,
* to replace an existing global VM
*
* default = false
*/
setReplacementPermission(false);
if (rsvc.getBoolean(
RuntimeConstants.VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL, false))
{
setReplacementPermission(true);
log.info("allowInlineToOverride = true : VMs " +
"defined inline may replace previous VM definitions");
}
else
{
log.debug("allowInlineToOverride = false : VMs " +
"defined inline may NOT replace previous VM definitions");
}
/*
* now turn on namespace handling as far as permissions allow in the
* manager, and also set it here for gating purposes
*/
vmManager.setNamespaceUsage(true);
/*
* template-local inline VM mode : default is off
*/
setTemplateLocalInline(rsvc.getBoolean(
RuntimeConstants.VM_PERM_INLINE_LOCAL, false));
if (getTemplateLocalInline())
{
log.info("allowInlineLocal = true : VMs " +
"defined inline will be local to their defining template only.");
}
else
{
log.debug("allowInlineLocal = false : VMs " +
"defined inline will be global in scope if allowed.");
}
vmManager.setTemplateLocalInlineVM(getTemplateLocalInline());
/*
* autoload VM libraries
*/
setAutoload(rsvc.getBoolean(RuntimeConstants.VM_LIBRARY_AUTORELOAD, false));
if (getAutoload())
{
log.info("autoload on : VM system " +
"will automatically reload global library macros");
}
else
{
log.debug("autoload off : VM system " +
"will not automatically reload global library macros");
}
log.trace("Velocimacro : initialization complete.");
}
}
/**
* adds a macro to the factory.
*
* @param name Name of the Macro to add.
* @param macroBody String representation of the macro.
* @param argArray Macro arguments. First element is the macro name.
* @param sourceTemplate Source template from which the macro gets registered.
* @return True if Macro was registered successfully.
*/
public boolean addVelocimacro(String name, String macroBody,
String argArray[], String sourceTemplate)
{
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -