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