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    }