001    package railo.runtime.tag;
002    
003    import railo.runtime.exp.TemplateException;
004    import railo.runtime.ext.tag.TagImpl;
005    import railo.runtime.type.Scope;
006    
007    /**
008    * Used to: Abort the processing of the currently executing CFML custom tag, exit the template 
009    *       within the currently executing CFML custom tag and reexecute a section of code within the currently
010    *       executing CFML custom tag
011    *
012    *
013    *
014    **/
015    public final class Exit extends TagImpl {
016    
017            private static final short MODE_LOOP=0;
018            private static final short MODE_EXIT_TAG=1;
019            private static final short MODE_EXIT_TEMPLATE=2;
020            /**  */
021            private short method=MODE_EXIT_TAG;
022    
023            /**
024            * @see javax.servlet.jsp.tagext.Tag#release()
025            */
026            public void release()   {
027                    super.release();
028                    method=MODE_EXIT_TAG;
029            }
030    
031    
032            /** set the value method
033            *  
034            * @param method value to set
035            **/
036            public void setMethod(String method)    {
037                    method=method.toLowerCase();
038                    if(method.equals("loop"))this.method=MODE_LOOP;
039                    else if(method.equals("exittag"))this.method=MODE_EXIT_TAG;
040                    else if(method.equals("exittemplate"))this.method=MODE_EXIT_TEMPLATE;
041            }
042    
043    
044            /**
045            * @see javax.servlet.jsp.tagext.Tag#doStartTag()
046            */
047            public int doStartTag() {
048                    return SKIP_BODY;
049            }
050    
051            /**
052            * @see javax.servlet.jsp.tagext.Tag#doEndTag()
053            */
054            public int doEndTag() throws TemplateException  {
055                    Scope variables = pageContext.variablesScope();
056                    Object thistagObj=variables.get("thistag",null);
057                    boolean insideCT=(thistagObj !=null) && (thistagObj instanceof railo.runtime.type.Collection);
058                    //executebody
059    
060                    // Inside Custom Tag
061                    if(insideCT) {
062                            railo.runtime.type.Collection thistag=(railo.runtime.type.Collection) thistagObj;
063                            //executionmode
064                            Object exeModeObj=thistag.get("executionmode",null);
065                            boolean isEndMode=(exeModeObj !=null) && (exeModeObj instanceof String) && exeModeObj.toString().equalsIgnoreCase("end");
066                            
067                            // Start
068                            if(!isEndMode) {
069                                    if(method==MODE_LOOP) {
070                                            throw new TemplateException("invalid context for the tag exit, method loop can only be used in the end tag of a custom tag");
071                                    }
072                                    else if(method==MODE_EXIT_TAG) {
073                                            thistag.setEL("executebody",Boolean.FALSE);
074                                            return SKIP_PAGE;
075                                    }
076                            }
077                            // End
078                            else if(method==MODE_LOOP) {
079                                    thistag.setEL("executebody",Boolean.TRUE);
080                                    return SKIP_PAGE;
081                            }
082                            return SKIP_PAGE;
083                    }
084                    
085                    // OUTside Custom Tag
086                    if(method==MODE_LOOP) throw new TemplateException("invalid context for the tag exit, method loop can only be used inside a custom tag");
087                    return SKIP_PAGE;
088                    
089            }       
090    }