mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Webscript scripturl() method encoding now supported in PageRenderer website framework
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6897 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -35,6 +35,7 @@ import java.io.OutputStreamWriter;
|
|||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -100,7 +101,9 @@ public class PageRendererServlet extends WebScriptServlet
|
|||||||
private static Log logger = LogFactory.getLog(PageRendererServlet.class);
|
private static Log logger = LogFactory.getLog(PageRendererServlet.class);
|
||||||
|
|
||||||
private static final String MIMETYPE_HTML = "text/html;charset=utf-8";
|
private static final String MIMETYPE_HTML = "text/html;charset=utf-8";
|
||||||
|
private static final String PARAM_COMPONENT_ID = "_alfId";
|
||||||
|
private static final String PARAM_COMPONENT_URL = "_alfUrl";
|
||||||
|
|
||||||
private PageTemplateProcessor templateProcessor;
|
private PageTemplateProcessor templateProcessor;
|
||||||
private WebScriptTemplateLoader webscriptTemplateLoader;
|
private WebScriptTemplateLoader webscriptTemplateLoader;
|
||||||
private Map<String, PageDefinition> defaultPageDefCache = null;
|
private Map<String, PageDefinition> defaultPageDefCache = null;
|
||||||
@@ -194,11 +197,24 @@ public class PageRendererServlet extends WebScriptServlet
|
|||||||
authenticate(getServletContext(), req, res);
|
authenticate(getServletContext(), req, res);
|
||||||
|
|
||||||
// set the web app context path for the template loader to use when rebuilding urls
|
// set the web app context path for the template loader to use when rebuilding urls
|
||||||
LoaderPageContext context = new LoaderPageContext();
|
PageRendererContext context = new PageRendererContext();
|
||||||
context.Path = req.getContextPath();
|
context.RequestURI = uri;
|
||||||
|
context.RequestPath = req.getContextPath();
|
||||||
context.PageDef = pageDefinition;
|
context.PageDef = pageDefinition;
|
||||||
context.AVMStore = store;
|
context.AVMStore = store;
|
||||||
context.Theme = theme;
|
context.Theme = theme;
|
||||||
|
|
||||||
|
// look for clicked component id+url
|
||||||
|
// TODO: keep state of page? i.e. multiple webscripts can be hosted and clicked...
|
||||||
|
String compId = req.getParameter(PARAM_COMPONENT_ID);
|
||||||
|
if (compId != null)
|
||||||
|
{
|
||||||
|
String compUrl = req.getParameter(PARAM_COMPONENT_URL);
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Clicked component found: " + compId + " URL: " + compUrl);
|
||||||
|
context.ComponentId = compId;
|
||||||
|
context.ComponentUrl = compUrl;
|
||||||
|
}
|
||||||
pageDefinition.Theme = theme;
|
pageDefinition.Theme = theme;
|
||||||
this.webscriptTemplateLoader.setContext(context);
|
this.webscriptTemplateLoader.setContext(context);
|
||||||
|
|
||||||
@@ -257,6 +273,7 @@ public class PageRendererServlet extends WebScriptServlet
|
|||||||
{
|
{
|
||||||
// Lookup (and cache) config for default page-definition file in root
|
// Lookup (and cache) config for default page-definition file in root
|
||||||
PageDefinition defaultPageDef = defaultPageDefCache.get(store);
|
PageDefinition defaultPageDef = defaultPageDefCache.get(store);
|
||||||
|
// TODO: check last modified date (use auto-timeout cache object!)
|
||||||
if (defaultPageDef == null)
|
if (defaultPageDef == null)
|
||||||
{
|
{
|
||||||
// read default config for the site and cache the result
|
// read default config for the site and cache the result
|
||||||
@@ -436,21 +453,19 @@ public class PageRendererServlet extends WebScriptServlet
|
|||||||
*/
|
*/
|
||||||
private class PageRendererWebScriptRuntime extends WebScriptRuntime
|
private class PageRendererWebScriptRuntime extends WebScriptRuntime
|
||||||
{
|
{
|
||||||
|
private PageComponent component;
|
||||||
|
private PageRendererContext context;
|
||||||
private String webScript;
|
private String webScript;
|
||||||
private String scriptUrl;
|
private String scriptUrl;
|
||||||
private String encoding;
|
private String encoding;
|
||||||
private String avmStore;
|
|
||||||
private String theme;
|
|
||||||
private PageComponent component;
|
|
||||||
private ByteArrayOutputStream baOut = null;
|
private ByteArrayOutputStream baOut = null;
|
||||||
|
|
||||||
PageRendererWebScriptRuntime(
|
PageRendererWebScriptRuntime(
|
||||||
PageComponent component, String avmStore, String theme, String webScript, String executeUrl, String encoding)
|
PageComponent component, PageRendererContext context, String webScript, String executeUrl, String encoding)
|
||||||
{
|
{
|
||||||
super(registry, serviceRegistry);
|
super(registry, serviceRegistry);
|
||||||
this.component = component;
|
this.component = component;
|
||||||
this.avmStore = avmStore;
|
this.context = context;
|
||||||
this.theme = theme;
|
|
||||||
this.webScript = webScript;
|
this.webScript = webScript;
|
||||||
this.scriptUrl = executeUrl;
|
this.scriptUrl = executeUrl;
|
||||||
this.encoding = encoding;
|
this.encoding = encoding;
|
||||||
@@ -470,9 +485,9 @@ public class PageRendererServlet extends WebScriptServlet
|
|||||||
// set the component properties as the additional request attributes
|
// set the component properties as the additional request attributes
|
||||||
Map<String, String> attributes = new HashMap<String, String>();
|
Map<String, String> attributes = new HashMap<String, String>();
|
||||||
attributes.putAll(component.Properties);
|
attributes.putAll(component.Properties);
|
||||||
// add the well known attribute - such as avm store
|
// add the "well known" attributes - such as avm store
|
||||||
attributes.put("store", this.avmStore);
|
attributes.put("store", this.context.AVMStore);
|
||||||
attributes.put("theme", this.theme);
|
attributes.put("theme", this.context.Theme);
|
||||||
return new WebScriptPageRendererRequest(scriptUrl, match, attributes);
|
return new WebScriptPageRendererRequest(scriptUrl, match, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,7 +501,7 @@ public class PageRendererServlet extends WebScriptServlet
|
|||||||
this.baOut = new ByteArrayOutputStream(4096);
|
this.baOut = new ByteArrayOutputStream(4096);
|
||||||
BufferedWriter wrOut = new BufferedWriter(
|
BufferedWriter wrOut = new BufferedWriter(
|
||||||
encoding == null ? new OutputStreamWriter(baOut) : new OutputStreamWriter(baOut, encoding));
|
encoding == null ? new OutputStreamWriter(baOut) : new OutputStreamWriter(baOut, encoding));
|
||||||
return new WebScriptPageRendererResponse(wrOut, baOut);
|
return new WebScriptPageRendererResponse(context, component.Id, wrOut, baOut);
|
||||||
}
|
}
|
||||||
catch (UnsupportedEncodingException err)
|
catch (UnsupportedEncodingException err)
|
||||||
{
|
{
|
||||||
@@ -584,19 +599,31 @@ public class PageRendererServlet extends WebScriptServlet
|
|||||||
{
|
{
|
||||||
private Writer outWriter;
|
private Writer outWriter;
|
||||||
private OutputStream outStream;
|
private OutputStream outStream;
|
||||||
|
private PageRendererContext context;
|
||||||
|
private String componentId;
|
||||||
|
|
||||||
public WebScriptPageRendererResponse(Writer outWriter, OutputStream outStream)
|
public WebScriptPageRendererResponse(
|
||||||
|
PageRendererContext context, String componentId, Writer outWriter, OutputStream outStream)
|
||||||
{
|
{
|
||||||
|
this.context = context;
|
||||||
|
this.componentId = componentId;
|
||||||
this.outWriter = outWriter;
|
this.outWriter = outWriter;
|
||||||
this.outStream = outStream;
|
this.outStream = outStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String encodeScriptUrl(String url)
|
public String encodeScriptUrl(String url)
|
||||||
{
|
{
|
||||||
// TODO: some kind of encoding required here - need to allow webscripts to call themselves
|
// encode to allow presentation tier webscripts to call themselves non this page
|
||||||
// on this page - so need the servlet PageRenderer URL plus args to identify the webscript
|
// needs the servlet URL plus args to identify the webscript and it's new url
|
||||||
// and it's new url - similar to the JSF or Portlet runtimes
|
try
|
||||||
return url;
|
{
|
||||||
|
return context.RequestPath + context.RequestURI + "?" + PARAM_COMPONENT_URL + "=" +
|
||||||
|
URLEncoder.encode(url, "UTF-8") + "&" + PARAM_COMPONENT_ID + "=" + componentId;
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException err)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Unable to encode UTF-8 format URL: " + url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEncodeScriptUrlFunction(String name)
|
public String getEncodeScriptUrlFunction(String name)
|
||||||
@@ -642,7 +669,7 @@ public class PageRendererServlet extends WebScriptServlet
|
|||||||
*/
|
*/
|
||||||
private class WebScriptTemplateLoader implements TemplateLoader
|
private class WebScriptTemplateLoader implements TemplateLoader
|
||||||
{
|
{
|
||||||
private ThreadLocal<LoaderPageContext> context = new ThreadLocal<LoaderPageContext>();
|
private ThreadLocal<PageRendererContext> context = new ThreadLocal<PageRendererContext>();
|
||||||
private long last = 0L;
|
private long last = 0L;
|
||||||
|
|
||||||
public void closeTemplateSource(Object templateSource) throws IOException
|
public void closeTemplateSource(Object templateSource) throws IOException
|
||||||
@@ -688,11 +715,11 @@ public class PageRendererServlet extends WebScriptServlet
|
|||||||
String key = templateSource.toString();
|
String key = templateSource.toString();
|
||||||
|
|
||||||
// lookup against component def config
|
// lookup against component def config
|
||||||
LoaderPageContext context = this.context.get();
|
PageRendererContext context = this.context.get();
|
||||||
PageComponent component = context.PageDef.Components.get(key);
|
PageComponent component = context.PageDef.Components.get(key);
|
||||||
if (component == null)
|
if (component == null)
|
||||||
{
|
{
|
||||||
// TODO: if the lookup fails, exception or just ignore render and log...?
|
// TODO: if the lookup fails, throw exception or just ignore the render and log...?
|
||||||
throw new AlfrescoRuntimeException("Failed to find component identified by key '" + key +
|
throw new AlfrescoRuntimeException("Failed to find component identified by key '" + key +
|
||||||
"' found in template: " + context.PageDef.TemplateName);
|
"' found in template: " + context.PageDef.TemplateName);
|
||||||
}
|
}
|
||||||
@@ -709,16 +736,24 @@ public class PageRendererServlet extends WebScriptServlet
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Execute the webscript and return a Reader to the textual content
|
// Execute the webscript and return a Reader to the textual content
|
||||||
String executeUrl = context.Path + component.Url;
|
String executeUrl;
|
||||||
|
if (component.Id.equals(context.ComponentId) == false)
|
||||||
|
{
|
||||||
|
executeUrl = context.RequestPath + component.Url;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// found the component url that was passed in on the servlet request
|
||||||
|
executeUrl = context.ComponentUrl;
|
||||||
|
}
|
||||||
PageRendererWebScriptRuntime runtime = new PageRendererWebScriptRuntime(
|
PageRendererWebScriptRuntime runtime = new PageRendererWebScriptRuntime(
|
||||||
component, context.AVMStore, context.Theme, webscript, executeUrl, encoding);
|
component, context, webscript, executeUrl, encoding);
|
||||||
runtime.executeScript();
|
runtime.executeScript();
|
||||||
|
|
||||||
// Return a reader from the runtime that executed the webscript - this effectively
|
// Return a reader from the runtime that executed the webscript - this effectively
|
||||||
// returns the result as a "template" source to freemarker. Generally this will not itself
|
// returns the result as a "template" source to freemarker. Generally this will not itself
|
||||||
// be a template but it can contain additional freemarker syntax if required. The downside
|
// be a template but it can contain additional freemarker syntax if required - it is up to
|
||||||
// to this approach is that the result of the webscript is parsed again by freemarker - this
|
// the template writer to add the parse=[true|false] attribute as appropriate to the #include
|
||||||
// should be checked for performance issues.
|
|
||||||
return runtime.getResponseReader();
|
return runtime.getResponseReader();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -727,21 +762,24 @@ public class PageRendererServlet extends WebScriptServlet
|
|||||||
* to allow multiple servlet threads to execute using the same TemplateLoader (there can only be one)
|
* to allow multiple servlet threads to execute using the same TemplateLoader (there can only be one)
|
||||||
* but with a different context for each thread.
|
* but with a different context for each thread.
|
||||||
*/
|
*/
|
||||||
public void setContext(LoaderPageContext context)
|
public void setContext(PageRendererContext context)
|
||||||
{
|
{
|
||||||
this.context.set(context);
|
this.context.set(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple structure class representing the current page context for the template loader
|
* Simple structure class representing the current page request context
|
||||||
*/
|
*/
|
||||||
private static class LoaderPageContext
|
private static class PageRendererContext
|
||||||
{
|
{
|
||||||
PageDefinition PageDef;
|
PageDefinition PageDef;
|
||||||
String Path;
|
String RequestURI;
|
||||||
|
String RequestPath;
|
||||||
String AVMStore;
|
String AVMStore;
|
||||||
String Theme;
|
String Theme;
|
||||||
|
String ComponentId;
|
||||||
|
String ComponentUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -83,7 +83,17 @@ public final class ScriptUrlMethod implements TemplateMethodModelEx
|
|||||||
StringBuffer buf = new StringBuffer(128);
|
StringBuffer buf = new StringBuffer(128);
|
||||||
buf.append(prefixServiceUrl ? req.getServicePath() : "");
|
buf.append(prefixServiceUrl ? req.getServicePath() : "");
|
||||||
buf.append(arg);
|
buf.append(arg);
|
||||||
buf.append(arg.length() != 0 ? "&" : "");
|
if (arg.length() != 0)
|
||||||
|
{
|
||||||
|
if (arg.indexOf('?') == -1)
|
||||||
|
{
|
||||||
|
buf.append('?');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf.append('&');
|
||||||
|
}
|
||||||
|
}
|
||||||
buf.append("guest=" + (req.isGuest() ? "true" : ""));
|
buf.append("guest=" + (req.isGuest() ? "true" : ""));
|
||||||
if (req.getFormatStyle() == FormatStyle.argument)
|
if (req.getFormatStyle() == FormatStyle.argument)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user