Skip to content

Commit

Permalink
fix Resource not found for the first rendering, refs #118
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaochong committed May 15, 2013
1 parent 9ddadef commit 8713ad7
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 1 deletion.
3 changes: 2 additions & 1 deletion ZkuiGrailsPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.grails.plugins.zkui.metaclass.RedirectDynamicMethod
import org.grails.plugins.zkui.util.ComponentErrorRendererUtil
import org.grails.plugins.zkui.util.UriUtil
import org.springframework.web.context.request.RequestContextHolder as RCH
import org.zkoss.lang.Library
import org.zkoss.zk.ui.Component
import org.zkoss.zk.ui.Executions
import org.zkoss.zk.ui.Page
Expand Down Expand Up @@ -324,7 +325,7 @@ The different is it more likely to use the Grails' infrastructures such as gsp,
}

def doWithApplicationContext = { applicationContext ->
// TODO Implement post initialization spring config (optional)
Library.setProperty("org.zkoss.web.servlet.http.URLEncoder", "org.grails.plugins.zkui.encodes.URLEncoder")
}

def onChange = { event ->
Expand Down
165 changes: 165 additions & 0 deletions src/java/org/grails/plugins/zkui/encodes/URLEncoder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package org.grails.plugins.zkui.encodes;

import org.zkoss.util.logging.Log;
import org.zkoss.web.servlet.Charsets;
import org.zkoss.web.servlet.Servlets;
import org.zkoss.web.servlet.http.Encodes;
import org.zkoss.web.servlet.http.Https;
import org.zkoss.web.util.resource.ExtendletContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class URLEncoder implements org.zkoss.web.servlet.http.Encodes.URLEncoder {
private static final Log log = Log.lookup(Https.class);

/**
* unsafe character when that are used in url's location.
*/
private static final char[] URI_UNSAFE;
/**
* unsafe character when that are used in url's query.
*/
private static final char[] URI_COMP_UNSAFE;

static {
URI_UNSAFE = "`%^{}[]\\\"<>|".toCharArray();
Arrays.sort(URI_UNSAFE);

URI_COMP_UNSAFE = "`%^{}[]\\\"<>|$&,/:;=?".toCharArray();
Arrays.sort(URI_COMP_UNSAFE);
}

public String encodeURL(ServletContext ctx, ServletRequest request, ServletResponse response, String url, Encodes.URLEncoder defaultEncoder) throws Exception {
return encodeURL0(ctx, request, response, url);
}

private static final String encodeURL0(ServletContext ctx,
ServletRequest request, ServletResponse response, String uri)
throws Exception {
if (uri == null || uri.length() == 0)
return uri; //keep as it is

boolean ctxpathSpecified = false;
if (uri.charAt(0) != '/') { //NOT relative to context path
if (Servlets.isUniversalURL(uri)) return uri; //nothing to do

if (uri.charAt(0) == '~') { //foreign context
final String ctxroot;
if (uri.length() == 1) {
ctxroot = uri = "/";
} else if (uri.charAt(1) == '/') {
ctxroot = "/";
uri = uri.substring(1);
} else {
uri = '/' + uri.substring(1);
final int j = uri.indexOf('/', 1);
ctxroot = j >= 0 ? uri.substring(0, j) : uri;
}

final ExtendletContext extctx =
Servlets.getExtendletContext(ctx, ctxroot.substring(1));
if (extctx != null) {
final int j = uri.indexOf('/', 1);
return extctx.encodeURL(request, response,
j >= 0 ? uri.substring(j) : "/");
}

final ServletContext newctx = ctx.getContext(ctxroot);
if (newctx != null) {
ctx = newctx;
} else if (log.debugable()) {
log.debug("Context not found: " + ctxroot);
}
ctxpathSpecified = true;
} else if (Https.isIncluded(request) || Https.isForwarded(request)) {
//if reletive URI and being included/forwarded,
//converts to absolute
String pgpath = Https.getThisServletPath(request);
if (pgpath != null) {
int j = pgpath.lastIndexOf('/');
if (j >= 0) {
uri = pgpath.substring(0, j + 1) + uri;
} else {
log.warning("The current page doesn't contain '/':" + pgpath);
}
}
}
}

//locate by locale and browser if necessary
uri = Servlets.locate(ctx, request, uri, null);

//prefix context path
if (!ctxpathSpecified && uri.charAt(0) == '/'
&& (request instanceof HttpServletRequest)) {
//Work around with a bug when we wrap Pluto's RenderRequest (1.0.1)
String ctxpath = ((HttpServletRequest) request).getContextPath();
if (ctxpath.length() > 0 && ctxpath.charAt(0) != '/')
ctxpath = '/' + ctxpath;

//Some Web server's ctxpath is "/"
final int last = ctxpath.length() - 1;
if (last >= 0 && ctxpath.charAt(last) == '/')
ctxpath = ctxpath.substring(0, last);

uri = ctxpath + uri;
}

int j = uri.indexOf('?');
if (j < 0) {
uri = encodeURI(uri);
} else {
uri = encodeURI(uri.substring(0, j)) + uri.substring(j);
}
//encode
// if (response instanceof HttpServletResponse)
// uri = ((HttpServletResponse) response).encodeURL(uri);
return uri;
}

public static final String encodeURI(String s)
throws UnsupportedEncodingException {
return encodeURI0(s, URI_UNSAFE);
}

public static final String encodeURIComponent(String s)
throws UnsupportedEncodingException {
return encodeURI0(s, URI_COMP_UNSAFE);
}

private static final String encodeURI0(String s, char[] unsafes)
throws UnsupportedEncodingException {
if (s == null)
return null;

final String charset = Charsets.getURICharset();
final byte[] in = s.getBytes(charset);
final byte[] out = new byte[in.length * 3];//at most: %xx
int j = 0, k = 0;
for (; j < in.length; ++j) {
//Though it is ok to use '+' for ' ', Jetty has problem to
//handle space between chinese characters.
final char cc = (char) (((int) in[j]) & 0xff);
if (cc >= 0x80 || cc <= ' '
|| Arrays.binarySearch(unsafes, cc) >= 0) {
out[k++] = (byte) '%';
String cvt = Integer.toHexString(cc);
if (cvt.length() == 1) {
out[k++] = (byte) '0';
out[k++] = (byte) cvt.charAt(0);
} else {
out[k++] = (byte) cvt.charAt(0);
out[k++] = (byte) cvt.charAt(1);
}
} else {
out[k++] = in[j];
}
}
return j == k ? s : new String(out, 0, k, charset);
}
}

0 comments on commit 8713ad7

Please sign in to comment.