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