001    package railo.commons.io;
002    import javax.servlet.http.HttpServletRequest;
003    import javax.servlet.http.HttpServletResponse;
004    import javax.servlet.jsp.JspWriter;
005    import javax.servlet.jsp.tagext.BodyContent;
006    
007    import railo.runtime.writer.BodyContentImpl;
008    import railo.runtime.writer.CFMLWriter;
009    import railo.runtime.writer.CFMLWriterImpl;
010    import railo.runtime.writer.CFMLWriterWhiteSpace;
011    import railo.runtime.writer.DevNullBodyContent;
012    
013    /**
014     * Stack for the Body Content Objects
015     */
016    public final class BodyContentStack {
017    
018        private CFMLWriter base;
019        
020        private final DevNullBodyContent nirvana=new DevNullBodyContent();
021        private Entry current;
022        private final Entry root;
023        
024        
025        /**
026         * Default Constructor
027         */
028        public BodyContentStack() {
029            current=new Entry(null,null);
030            root=current;
031        }
032    
033        /**
034         * initialize the BodyContentStack
035         * @param rsp
036         */
037        public void init(HttpServletRequest req, HttpServletResponse rsp, boolean suppresswhitespace, boolean closeConn, boolean showVersion, boolean contentLength,boolean allowCompression) {
038    //      this.base=new JSPWriterWhiteSpace(rsp,-1,false);
039            if(suppresswhitespace)
040                this.base=new CFMLWriterWhiteSpace(req,rsp,-1,false,closeConn,showVersion,contentLength,allowCompression);
041            else 
042                this.base=new CFMLWriterImpl(req,rsp,-1,false,closeConn,showVersion,contentLength,allowCompression);
043        }
044    
045        /**
046         * release the BodyContentStack
047         */
048        public void release() {
049            this.base=null;
050            current=root;
051            current.body=null;
052            current.after=null;
053            current.before=null;
054        }
055        
056    
057        /**
058         * push a new BodyContent to Stack
059         * @return new BodyContent
060         */
061        public BodyContent push() {
062            if(current.after==null) {
063                current.after=new Entry(current,new BodyContentImpl(current.body==null?(JspWriter)base:current.body));
064            }
065            else {
066                current.after.doDevNull=false;
067                current.after.body.init(current.body==null?(JspWriter)base:current.body);
068            }
069            current=current.after;
070            return current.body;
071        }
072        
073        /**
074         * pop a BodyContent from Stack
075         * @return BodyContent poped
076         */
077        public JspWriter pop() {
078            if(current.before!=null) current=current.before;
079            return getWriter();
080        }
081        
082        /**
083         * set if actuell BodyContent is DevNull or not
084         * @param doDevNull
085         */
086        public void setDevNull(boolean doDevNull) {
087            current.doDevNull=doDevNull;
088        }
089        
090        /**
091         * @return returns actuell writer
092         */
093        public JspWriter getWriter() {
094            if(!current.doDevNull) {
095                if(current.body!=null) return current.body;
096                return base;
097            }
098            return nirvana;
099        }
100        
101        
102        class Entry {
103            private Entry before;
104            private Entry after;
105            private boolean doDevNull=false;
106            private BodyContentImpl body;
107            private Entry(Entry before, BodyContentImpl body) {
108                this.before=before;
109                this.body=body;
110            }
111            
112        }
113    
114        /**
115         * @return returns DevNull Object
116         */
117        public boolean getDevNull() {
118            return current.doDevNull;
119        }
120    
121        /**
122         * @return returns DevNull Object
123         */
124        public DevNullBodyContent getDevNullBodyContent() {
125            return nirvana;
126        }
127    
128        /**
129         * @return Returns the base.
130         */
131        public CFMLWriter getBase() {
132            return base;
133        }
134    
135    }