001    package railo.runtime.tag;
002    
003    import java.io.IOException;
004    
005    import javax.servlet.jsp.tagext.Tag;
006    
007    import railo.commons.lang.StringUtil;
008    import railo.commons.pdf.PDFPageMark;
009    import railo.runtime.exp.ApplicationException;
010    import railo.runtime.exp.PageException;
011    import railo.runtime.ext.tag.BodyTagImpl;
012    import railo.runtime.op.Caster;
013    
014    public final class DocumentItem extends BodyTagImpl {
015    
016            private static final int TYPE_PAGE_BREAK = 0;
017            private static final int TYPE_HEADER = 1;
018            private static final int TYPE_FOOTER = 2;
019            private static final int TYPE_BOOKMARK = 3;
020    
021            private int type;
022            private String name;
023            private PDFPageMark body;
024            private boolean evalAtPrint;
025            
026            @Override
027            public void release() {
028                    super.release();
029                    this.body=null;
030                    name=null;
031            }
032    
033            /**
034             * @param type the type to set
035             * @throws ApplicationException 
036             */
037            public void setType(String strType) throws ApplicationException {
038                    strType=StringUtil.toLowerCase(strType.trim());
039                    if("pagebreak".equals(strType))         type=TYPE_PAGE_BREAK;
040                    else if("header".equals(strType))       type=TYPE_HEADER;
041                    else if("footer".equals(strType))       type=TYPE_FOOTER;
042                    else if("bookmark".equals(strType))     type=TYPE_BOOKMARK;
043                    else throw new ApplicationException("invalid type ["+strType+"], valid types are [pagebreak,header,footer,bookmark]");
044                    //else throw new ApplicationException("invalid type ["+strType+"], valid types are [pagebreak,header,footer]");
045                    
046            }
047    
048            public void setEvalatprint(boolean evalAtPrint){
049                    this.evalAtPrint=evalAtPrint;
050            }
051    
052        @Override
053            public int doStartTag() {
054                    return EVAL_BODY_BUFFERED;
055            }
056    
057            @Override
058            public void doInitBody()        {}
059            
060            @Override
061            public int doAfterBody()        {
062                    if(TYPE_HEADER==type || TYPE_FOOTER==type) {
063                            body=new PDFPageMark(-1,translate(bodyContent.getString()));
064                    }
065                    
066                    return SKIP_BODY;
067            }
068            
069            private String translate(String html) {
070                    html=StringUtil.replace(html.trim(), "{currentsectionpagenumber}", "${page}", false);
071                    html=StringUtil.replace(html, "{totalsectionpagecount}", "${total}", false);
072                    
073                    html=StringUtil.replace(html.trim(), "{currentpagenumber}", "${page}", false);
074                    html=StringUtil.replace(html, "{totalpagecount}", "${total}", false);
075                    
076    
077                //cfdoc.setEL("currentpagenumber", "{currentpagenumber}");
078                //cfdoc.setEL("totalpagecount", "{totalpagecount}");
079                
080                    
081                    return html;
082            }
083    
084            @Override
085            public int doEndTag() throws PageException {
086                    try {
087                            _doEndTag();
088                    }
089                    catch (Exception e) {
090                            throw Caster.toPageException(e);
091                    }       
092                    return EVAL_PAGE;
093            }
094            private void _doEndTag() throws IOException, ApplicationException {
095                    if(TYPE_PAGE_BREAK==type) {
096                            pageContext.forceWrite("<pd4ml:page.break>");
097                            return;
098                    }
099                    else if(TYPE_BOOKMARK==type) {
100                            if(StringUtil.isEmpty(name))
101                                    throw new ApplicationException("attribute [name] is required when type is [bookmark]");
102                            pageContext.forceWrite("<pd4ml:bookmark>"+name+"</pd4ml:bookmark>");
103                    }
104                    else if(body!=null) {
105                            provideDocumentItem();
106                    }
107                    
108            }
109    
110            private void provideDocumentItem()      {
111                    // get Document Tag
112                    Tag parent=getParent();
113                    while(parent!=null && !(parent instanceof Document) && !(parent instanceof DocumentSection)) {
114                            parent=parent.getParent();
115                    }
116    
117                    if(parent instanceof Document) {
118                            Document doc = (Document)parent;
119                            if(TYPE_HEADER==type)doc.setHeader(body);
120                            else if(TYPE_FOOTER==type)doc.setFooter(body);
121                            return ;
122                    }
123                    else if(parent instanceof DocumentSection) {
124                            DocumentSection doc = (DocumentSection)parent;
125                            if(TYPE_HEADER==type)doc.setHeader(body);
126                            else if(TYPE_FOOTER==type)doc.setFooter(body);
127                            return ;
128                    }
129            }
130            
131            /**
132             * sets if has body or not
133             * @param hasBody
134             */
135            public void hasBody(boolean hasBody) {
136                
137            }
138    
139            /**
140             * @param name the name to set
141             */
142            public void setName(String name) {
143                    this.name = name;
144            }
145    }