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    }