001 package railo.runtime.tag; 002 003 import java.util.HashMap; 004 import java.util.Map; 005 import java.util.Stack; 006 007 import javax.servlet.jsp.tagext.Tag; 008 009 import railo.commons.lang.ClassUtil; 010 import railo.runtime.config.ConfigWeb; 011 import railo.runtime.exp.ExpressionException; 012 import railo.runtime.exp.PageException; 013 import railo.runtime.op.Caster; 014 015 // TODO kann man nicht auf context ebene 016 017 /** 018 * Pool to Handle Tags 019 */ 020 public final class TagHandlerPool { 021 private Map<String,Stack<Tag>> map=new HashMap<String,Stack<Tag>>(); 022 private ConfigWeb config; 023 024 public TagHandlerPool(ConfigWeb config) { 025 this.config=config; 026 } 027 028 /** 029 * return a tag to use from a class 030 * @param tagClass 031 * @return Tag 032 * @throws PageException 033 */ 034 public Tag use(String tagClass) throws PageException { 035 Stack<Tag> stack = getStack(tagClass); 036 synchronized (stack) { 037 if(!stack.isEmpty()){ 038 Tag tag=stack.pop(); 039 if(tag!=null) return tag; 040 } 041 } 042 return loadTag(tagClass); 043 } 044 045 /** 046 * free a tag for reusing 047 * @param tag 048 * @throws ExpressionException 049 */ 050 public synchronized void reuse(Tag tag) { 051 tag.release(); 052 Stack<Tag> stack = getStack(tag.getClass().getName()); 053 synchronized (stack) { 054 stack.add(tag); 055 } 056 } 057 058 059 private Tag loadTag(String tagClass) throws PageException { 060 try { 061 Class<Tag> clazz = ClassUtil.loadClass(config.getClassLoader(),tagClass); 062 return clazz.newInstance(); 063 } 064 catch (Exception e) { 065 throw Caster.toPageException(e); 066 } 067 } 068 069 private Stack<Tag> getStack(String tagClass) { 070 synchronized (map) { 071 Stack<Tag> stack = map.get(tagClass); 072 if(stack==null) { 073 stack=new Stack<Tag>(); 074 map.put(tagClass,stack); 075 } 076 return stack; 077 } 078 } 079 080 public void reset() { 081 map.clear(); 082 } 083 }