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