001    package railo.runtime.tag;
002    
003    import java.io.IOException;
004    
005    import javax.servlet.http.HttpServletResponse;
006    
007    import railo.commons.lang.StringUtil;
008    import railo.commons.net.HTTPUtil;
009    import railo.runtime.exp.Abort;
010    import railo.runtime.exp.ApplicationException;
011    import railo.runtime.exp.NativeException;
012    import railo.runtime.exp.PageException;
013    import railo.runtime.ext.tag.TagImpl;
014    import railo.runtime.op.Caster;
015    import railo.runtime.util.ApplicationContext;
016    
017    
018    public final class Location extends TagImpl {
019    
020            /** Yes or No. clientManagement must be enabled, see cfapplication. Yes appends client variable 
021            **              information to the URL you specify in the url. */
022            private boolean addtoken=true;
023    
024            /** The URL of the HTML file or CFML page to open. */
025            private String url="";
026            
027            private int statuscode=302;
028            
029    
030            /**
031            * @see javax.servlet.jsp.tagext.Tag#release()
032            */
033            public void release()   {
034                    super.release();
035                    addtoken=true;
036                    url="";
037                    statuscode=302;
038            }
039    
040            /**
041             * @param statuscode the statuscode to set
042             * @throws ApplicationException 
043             */
044            public void setStatuscode(double statuscode) throws ApplicationException {
045                    int sc=(int) statuscode;
046                    if(sc<300 || sc>307) 
047                            throw new ApplicationException("invalid value for attribute statuscode ["+Caster.toString(statuscode)+"]",
048                                            "attribute must have one of the folloing values [300|301|302|303|304|305|307]");
049                            
050                    this.statuscode = sc;
051            }
052    
053    
054            /** set the value addtoken
055            *  Yes or No. clientManagement must be enabled, see cfapplication. Yes appends client variable 
056            *               information to the URL you specify in the url.
057            * @param addtoken value to set
058            **/
059            public void setAddtoken(boolean addtoken)       {
060                    this.addtoken=addtoken;
061            }
062    
063            /** set the value url
064            *  The URL of the HTML file or CFML page to open.
065            * @param url value to set
066             * @throws ApplicationException
067            **/
068            public void setUrl(String url) throws ApplicationException      {
069                    this.url=url.trim();
070                    if(this.url.length()==0) throw new ApplicationException("invalid url [empty string] for attribute url");
071                    if(StringUtil.hasLineFeed(url)) throw new ApplicationException("invalid url ["+url+"] for attribute url, carriage-return or line-feed inside the url are not allowed");
072            }
073    
074    
075            /**
076            * @see javax.servlet.jsp.tagext.Tag#doStartTag()
077            */
078            public int doStartTag() throws PageException    {
079                    try {
080                            pageContext.getOut().clear();
081                    } catch (IOException e) {
082                            throw Caster.toPageException(e);
083                    }
084                    HttpServletResponse rsp = pageContext. getHttpServletResponse();
085                    
086                    url=HTTPUtil.encode(url);
087                    
088                    // add token
089                    if(addtoken && needId()) {
090                            String[] arr=url.split("\\?");
091                            
092                            // only string_name
093                            if(arr.length==1) {
094                                    url+="?"+pageContext.getURLToken();
095                            }
096                            // script_name and query_string
097                            else if(arr.length>1) {
098                                    url=arr[0]+"?"+pageContext.getURLToken();
099                                    for(int i=1;i<arr.length;i++)url+="&"+arr[i]; 
100                            }
101                            url=rsp.encodeRedirectURL(url); 
102                    }
103                    
104                    rsp.setHeader("Connection", "close"); // IE unter IIS6, Win2K3 und Resin
105                    rsp.setStatus(statuscode);
106                    rsp.setHeader("location", url);
107                    
108                    
109                    try {
110                            pageContext.forceWrite("<html>\n<head>\n\t<title>Document Moved</title>\n");
111                            //pageContext.forceWrite("\t<script>window.location='"+JSStringFormat.invoke(url)+"';</script>\n");
112                            pageContext.forceWrite("</head>\n<body>\n\t<h1>Object Moved</h1>\n\t             <a HREF=\""+url+"\">here</a>\n");
113                            pageContext.forceWrite("</body>\n</html>");
114                    } catch (IOException e) {
115                            throw new NativeException(e);
116                    }
117            pageContext.getDebugger().setOutput(false);
118                    throw new Abort(Abort.SCOPE_REQUEST);
119            }
120            
121            
122    
123    
124            private boolean needId() {
125                    ApplicationContext ac = pageContext.getApplicationContext();
126                    return ac.isSetClientManagement() || ac.isSetSessionManagement();
127            }
128    
129            /**
130            * @see javax.servlet.jsp.tagext.Tag#doEndTag()
131            */
132            public int doEndTag()   {
133                    return EVAL_PAGE;
134            }
135    }