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.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            @Override
024            public void release()   {
025                    super.release();
026                    method=MODE_EXIT_TAG;
027            }
028    
029    
030            /** set the value method
031            *  
032            * @param method value to set
033            **/
034            public void setMethod(String method)    {
035                    method=method.toLowerCase();
036                    if(method.equals("loop"))this.method=MODE_LOOP;
037                    else if(method.equals("exittag"))this.method=MODE_EXIT_TAG;
038                    else if(method.equals("exittemplate"))this.method=MODE_EXIT_TEMPLATE;
039            }
040    
041    
042            @Override
043            public int doStartTag() {
044                    return SKIP_BODY;
045            }
046    
047            @Override
048            public int doEndTag() throws TemplateException  {
049                    Scope variables = pageContext.variablesScope();
050                    Object thistagObj=variables.get("thistag",null);
051                    boolean insideCT=(thistagObj !=null) && (thistagObj instanceof railo.runtime.type.Collection);
052                    //executebody
053    
054                    // Inside Custom Tag
055                    if(insideCT) {
056                            railo.runtime.type.Collection thistag=(railo.runtime.type.Collection) thistagObj;
057                            //executionmode
058                            Object exeModeObj=thistag.get("executionmode",null);
059                            boolean isEndMode=(exeModeObj !=null) && (exeModeObj instanceof String) && exeModeObj.toString().equalsIgnoreCase("end");
060                            
061                            // Start
062                            if(!isEndMode) {
063                                    if(method==MODE_LOOP) {
064                                            throw new TemplateException("invalid context for the tag exit, method loop can only be used in the end tag of a custom tag");
065                                    }
066                                    else if(method==MODE_EXIT_TAG) {
067                                            thistag.setEL("executebody",Boolean.FALSE);
068                                            return SKIP_PAGE;
069                                    }
070                            }
071                            // End
072                            else if(method==MODE_LOOP) {
073                                    thistag.setEL("executebody",Boolean.TRUE);
074                                    return SKIP_PAGE;
075                            }
076                            return SKIP_PAGE;
077                    }
078                    
079                    // OUTside Custom Tag
080                    if(method==MODE_LOOP) throw new TemplateException("invalid context for the tag exit, method loop can only be used inside a custom tag");
081                    return SKIP_PAGE;
082                    
083            }       
084    }