/* * */ package org.smartly.packages.velocity.impl.vtools.toolbox; import org.apache.velocity.VelocityContext; import org.smartly.commons.logging.Level; import org.smartly.commons.logging.util.LoggingUtils; import org.smartly.commons.util.BeanUtils; import org.smartly.commons.util.ExceptionUtils; import org.smartly.commons.util.FormatUtils; import org.smartly.commons.util.StringUtils; import org.smartly.packages.velocity.impl.vtools.*; import org.smartly.packages.velocity.impl.vtools.FmtTool; import org.smartly.packages.velocity.impl.vtools.MathTool; import org.smartly.packages.velocity.impl.vtools.SysTool; import java.util.*; /** * Toolbox is a container of 'static' vtools that are passed to context.<br/> * "Static" vtools are no-context vtools (usually singleton objects). * Use VLCToolbox metods to add/remove tool references.<br/> * NOTE: If vtools are not singleton, they are created from scratch * before each execution. * * @author angelo.geminiani */ public class VLCToolbox { private final List<VLCToolboxItem> _tools = new LinkedList<VLCToolboxItem>(); // lazy inizialide from _tools and keep synchronized with _tools. private VelocityContext __vcontext; private Map<String, Object> __mcontext; // ------------------------------------------------------------------------ // Constructor // ------------------------------------------------------------------------ private VLCToolbox() { // add default 'no-context' vtools this.initTools(); } // ------------------------------------------------------------------------ // p u b l i c // ------------------------------------------------------------------------ /** * Create a tool reference and add it to Toolbox. * * @param id Tool id (usually the Tool NAME) * @param toolClass Class reference of tool * @param args Arguments to pass at tool constructor */ public void add(final String id, final Class toolClass, final Object[] args, final boolean isSingleton) { final VLCToolboxItem item = new VLCToolboxItem(id, toolClass, args, isSingleton); this.add(item); } /** * Add tool reference * * @param item Tool reference */ public void add(final VLCToolboxItem item) { // add tool to list if (!_tools.contains(item)) { _tools.add(item); } // add tool to vcontext if (null != __vcontext) { try { if (!__vcontext.containsKey(item.getId())) { final Object tool = item.getInstance(); __vcontext.put(getName(tool), tool); } } catch (Throwable ignored) { } } // add tool to mcontext if (null != __mcontext) { try { if (!__mcontext.containsKey(item.getId())) { final Object tool = item.getInstance(); __mcontext.put(getName(tool), tool); } } catch (Throwable ignored) { } } } /** * Replace tool if exists, or add if does not exists. * * @param id Tool id * @param toolClass Class * @param args Array * @param isSingleton boolean */ public void replace(final String id, final Class toolClass, final Object[] args, final boolean isSingleton) { final VLCToolboxItem item = new VLCToolboxItem(id, toolClass, args, isSingleton); this.replace(item); } /** * Replace tool if exists, or add if does not exists. * * @param item Tool to replace */ public void replace(final VLCToolboxItem item) { this.remove(item.getId()); this.add(item); } /** * Remove tool reference from toolbox * * @param id Tool id * @return VLCToolboxItem */ public VLCToolboxItem remove(final String id) { // remove tool from vcontext if (null != __vcontext) { __vcontext.remove(id); } // remove tool from mcontext if (null != __mcontext) { __mcontext.remove(id); } // remove tool from list final VLCToolboxItem item = new VLCToolboxItem(id, null, null, false); final int index = _tools.indexOf(item); if (index > -1) { return _tools.remove(index); } return null; } /** * Return output string with a log of all installed vtools.<br/> * This method is useful for log or debug. * * @return String */ public String enumTools() { final StringBuilder result = new StringBuilder(); try { for (final VLCToolboxItem item : _tools) { StringUtils.append("\t" + item.toString(), result, "\n"); } } catch (Throwable t) { result.append(ExceptionUtils.getRealMessage(t)); } return result.toString(); } public VelocityContext getToolsContext() { if (null == __vcontext) { __vcontext = this.createVContext(); } return __vcontext; } public Map<String, Object> getToolsContextAsMap() { if (null == __mcontext) { __mcontext = this.createMContext(); } return __mcontext; } // ------------------------------------------------------------------------ // p r i v a t e // ------------------------------------------------------------------------ private void initTools() { // add Formatter for date and number add(FmtTool.NAME, FmtTool.class, null, true); // add Math helper. add(MathTool.NAME, MathTool.class, null, true); // add System helper add(SysTool.NAME, SysTool.class, null, true); // add Console helper add(ConsoleTool.NAME, ConsoleTool.class, null, true); // add Js helper add(ScriptTool.NAME, ScriptTool.class, null, true); // add App helper add(AppTool.NAME, AppTool.class, null, true); // add Dic helper add(org.smartly.commons.i18n.Dictionary.NAME, org.smartly.commons.i18n.Dictionary.class, null, true); // add JSON helper add(JSONTool.NAME, JSONTool.class, null, true); // add String helper add(StringTool.NAME, StringTool.class, null, true); // add Conversion helper add(ConvertTool.NAME, ConvertTool.class, null, true); // more vtools can be added using add command } private VelocityContext createVContext() { final VelocityContext vcontext = new VelocityContext(); //-- add static (no-context) vtools --// for (final VLCToolboxItem item : _tools) { try { final Object tool = item.getInstance(); vcontext.put(item.getId(), tool); } catch (Throwable ignored) { } } return vcontext; } private Map<String, Object> createMContext() { final Map<String, Object> mcontext = Collections.synchronizedMap(new HashMap<String, Object>()); //-- add static (no-context) vtools --// for (final VLCToolboxItem item : _tools) { try { final Object tool = item.getInstance(); mcontext.put(item.getId(), tool); } catch (Throwable ignored) { } } return mcontext; } // ------------------------------------------------------------------------ // S T A T I C // ------------------------------------------------------------------------ private static VLCToolbox __instance; public static VLCToolbox getInstance() { if (null == __instance) { __instance = new VLCToolbox(); } return __instance; } private static String getName(final Object instance) { final String result = (String) BeanUtils.getValueIfAny(instance, "name"); if (StringUtils.hasText(result)) { return result; } LoggingUtils.getLogger(VLCToolbox.class).log(Level.SEVERE, FormatUtils.format("INVALID TOOL IN TOOLBOX. Missing 'name' property, so a default name 'undefined' will be assigned: {0}", instance)); return "undefined"; } }