001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.tag;
020
021import java.io.IOException;
022
023import javax.servlet.jsp.tagext.Tag;
024
025import lucee.commons.lang.StringUtil;
026import lucee.commons.pdf.PDFPageMark;
027import lucee.runtime.exp.ApplicationException;
028import lucee.runtime.exp.PageException;
029import lucee.runtime.ext.tag.BodyTagImpl;
030import lucee.runtime.op.Caster;
031
032public final class DocumentItem extends BodyTagImpl {
033
034        private static final int TYPE_PAGE_BREAK = 0;
035        private static final int TYPE_HEADER = 1;
036        private static final int TYPE_FOOTER = 2;
037        private static final int TYPE_BOOKMARK = 3;
038
039        private int type;
040        private String name;
041        private PDFPageMark body;
042        private boolean evalAtPrint;
043        
044        @Override
045        public void release() {
046                super.release();
047                this.body=null;
048                name=null;
049        }
050
051        /**
052         * @param type the type to set
053         * @throws ApplicationException 
054         */
055        public void setType(String strType) throws ApplicationException {
056                strType=StringUtil.toLowerCase(strType.trim());
057                if("pagebreak".equals(strType))         type=TYPE_PAGE_BREAK;
058                else if("header".equals(strType))       type=TYPE_HEADER;
059                else if("footer".equals(strType))       type=TYPE_FOOTER;
060                else if("bookmark".equals(strType))     type=TYPE_BOOKMARK;
061                else throw new ApplicationException("invalid type ["+strType+"], valid types are [pagebreak,header,footer,bookmark]");
062                //else throw new ApplicationException("invalid type ["+strType+"], valid types are [pagebreak,header,footer]");
063                
064        }
065
066        public void setEvalatprint(boolean evalAtPrint){
067                this.evalAtPrint=evalAtPrint;
068        }
069
070    @Override
071        public int doStartTag() {
072                return EVAL_BODY_BUFFERED;
073        }
074
075        @Override
076        public void doInitBody()        {}
077        
078        @Override
079        public int doAfterBody()        {
080                if(TYPE_HEADER==type || TYPE_FOOTER==type) {
081                        body=new PDFPageMark(-1,translate(bodyContent.getString()));
082                }
083                
084                return SKIP_BODY;
085        }
086        
087        private String translate(String html) {
088                html=StringUtil.replace(html.trim(), "{currentsectionpagenumber}", "${page}", false);
089                html=StringUtil.replace(html, "{totalsectionpagecount}", "${total}", false);
090                
091                html=StringUtil.replace(html.trim(), "{currentpagenumber}", "${page}", false);
092                html=StringUtil.replace(html, "{totalpagecount}", "${total}", false);
093                
094
095            //cfdoc.setEL("currentpagenumber", "{currentpagenumber}");
096            //cfdoc.setEL("totalpagecount", "{totalpagecount}");
097            
098                
099                return html;
100        }
101
102        @Override
103        public int doEndTag() throws PageException {
104                try {
105                        _doEndTag();
106                }
107                catch (Exception e) {
108                        throw Caster.toPageException(e);
109                }       
110                return EVAL_PAGE;
111        }
112        private void _doEndTag() throws IOException, ApplicationException {
113                if(TYPE_PAGE_BREAK==type) {
114                        pageContext.forceWrite("<pd4ml:page.break>");
115                        return;
116                }
117                else if(TYPE_BOOKMARK==type) {
118                        if(StringUtil.isEmpty(name))
119                                throw new ApplicationException("attribute [name] is required when type is [bookmark]");
120                        pageContext.forceWrite("<pd4ml:bookmark>"+name+"</pd4ml:bookmark>");
121                }
122                else if(body!=null) {
123                        provideDocumentItem();
124                }
125                
126        }
127
128        private void provideDocumentItem()      {
129                // get Document Tag
130                Tag parent=getParent();
131                while(parent!=null && !(parent instanceof Document) && !(parent instanceof DocumentSection)) {
132                        parent=parent.getParent();
133                }
134
135                if(parent instanceof Document) {
136                        Document doc = (Document)parent;
137                        if(TYPE_HEADER==type)doc.setHeader(body);
138                        else if(TYPE_FOOTER==type)doc.setFooter(body);
139                        return ;
140                }
141                else if(parent instanceof DocumentSection) {
142                        DocumentSection doc = (DocumentSection)parent;
143                        if(TYPE_HEADER==type)doc.setHeader(body);
144                        else if(TYPE_FOOTER==type)doc.setFooter(body);
145                        return ;
146                }
147        }
148        
149        /**
150         * sets if has body or not
151         * @param hasBody
152         */
153        public void hasBody(boolean hasBody) {
154            
155        }
156
157        /**
158         * @param name the name to set
159         */
160        public void setName(String name) {
161                this.name = name;
162        }
163}