Adjusts code to Tiles 3

This commit is contained in:
Lukasz Lenart
2016-01-12 10:13:51 +01:00
parent 4638b33457
commit ace6a5d5ee
4 changed files with 104 additions and 162 deletions
@@ -33,68 +33,53 @@ import org.apache.struts2.views.JspSupportServlet;
import org.apache.struts2.views.freemarker.FreemarkerManager;
import org.apache.struts2.views.freemarker.FreemarkerResult;
import org.apache.struts2.views.freemarker.StrutsBeanWrapper;
import org.apache.tiles.Attribute;
import org.apache.tiles.context.TilesRequestContext;
import org.apache.tiles.freemarker.template.TilesFMModelRepository;
import org.apache.tiles.impl.InvalidTemplateException;
import org.apache.tiles.renderer.impl.AbstractTypeDetectingAttributeRenderer;
import org.apache.tiles.servlet.context.ServletTilesRequestContext;
import org.apache.tiles.servlet.context.ServletUtil;
import org.apache.tiles.request.Request;
import org.apache.tiles.request.render.Renderer;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class StrutsFreeMarkerAttributeRenderer extends AbstractTypeDetectingAttributeRenderer {
public class StrutsFreeMarkerAttributeRenderer implements Renderer {
private static Logger LOG = LogManager.getLogger(StrutsFreeMarkerAttributeRenderer.class);
@Override
public void write(Object value, Attribute attribute, TilesRequestContext request) throws IOException {
if (value != null) {
if (value instanceof String) {
LOG.trace("Rendering freemarker tile ...");
public void render(String path, Request request) throws IOException {
if (path != null) {
LOG.trace("Rendering freemarker tile ...");
ServletTilesRequestContext servletRequest = ServletUtil.getServletRequest(request);
HttpServletRequest httpRequest = servletRequest.getRequest();
ActionContext ctx = ServletActionContext.getActionContext((HttpServletRequest) request);
if (ctx == null) {
throw new ConfigurationException("There is no ActionContext for current request!");
}
ActionContext ctx = ServletActionContext.getActionContext(httpRequest);
if (ctx == null) {
throw new ConfigurationException("There is no ActionContext for current request!");
}
registerTilesBeanModel(ctx);
registerTilesBeanModel(ctx);
FreemarkerResult result = new FreemarkerResult(path);
result.setWriter(request.getWriter());
String include = (String) value;
FreemarkerResult result = new FreemarkerResult(include);
result.setWriter(request.getWriter());
Container container = ctx.getContainer();
container.inject(result);
Container container = ctx.getContainer();
container.inject(result);
try {
ActionInvocation invocation = ctx.getActionInvocation();
result.doExecute(include, invocation);
} catch (TemplateException e) {
LOG.error("Exception was thrown during rendering value {}: {}", value, e.getMessage());
throw new InvalidTemplateException(e);
}
} else {
LOG.error("Value {} is not a String, cannot render template!", value);
throw new InvalidTemplateException("Cannot render a template that is not a string: " + String.valueOf(value));
try {
ActionInvocation invocation = ctx.getActionInvocation();
result.doExecute(path, invocation);
} catch (TemplateException e) {
LOG.error("Exception was thrown during rendering value {}: {}", path, e.getMessage());
throw new InvalidTemplateException(e);
}
} else {
LOG.error("Value is null, cannot render template!");
LOG.error("Path is null, cannot render template!");
throw new InvalidTemplateException("Cannot render a null template");
}
}
public boolean isRenderable(Object value, Attribute attribute, TilesRequestContext request) {
if (value instanceof String) {
String string = (String) value;
return string.startsWith("/") && string.endsWith(".ftl");
}
return false;
@Override
public boolean isRenderable(String path, Request request) {
return path != null && path.startsWith("/") && path.endsWith(".ftl");
}
/**
@@ -22,13 +22,8 @@ package org.apache.struts2.tiles;
import ognl.OgnlException;
import ognl.OgnlRuntime;
import ognl.PropertyAccessor;
import org.apache.tiles.TilesApplicationContext;
import org.apache.tiles.TilesContainer;
import org.apache.tiles.context.ChainedTilesRequestContextFactory;
import org.apache.tiles.context.TilesRequestContext;
import org.apache.tiles.context.TilesRequestContextFactory;
import org.apache.tiles.definition.DefinitionsFactory;
import org.apache.tiles.definition.DefinitionsFactoryException;
import org.apache.tiles.definition.pattern.DefinitionPatternMatcherFactory;
import org.apache.tiles.definition.pattern.PatternDefinitionResolver;
import org.apache.tiles.definition.pattern.PrefixedPatternDefinitionResolver;
@@ -36,6 +31,7 @@ import org.apache.tiles.definition.pattern.regexp.RegexpDefinitionPatternMatcher
import org.apache.tiles.definition.pattern.wildcard.WildcardDefinitionPatternMatcherFactory;
import org.apache.tiles.el.ELAttributeEvaluator;
import org.apache.tiles.el.JspExpressionFactoryFactory;
import org.apache.tiles.el.ScopeELResolver;
import org.apache.tiles.el.TilesContextBeanELResolver;
import org.apache.tiles.el.TilesContextELResolver;
import org.apache.tiles.evaluator.AttributeEvaluatorFactory;
@@ -43,25 +39,22 @@ import org.apache.tiles.evaluator.BasicAttributeEvaluatorFactory;
import org.apache.tiles.evaluator.impl.DirectAttributeEvaluator;
import org.apache.tiles.factory.BasicTilesContainerFactory;
import org.apache.tiles.factory.TilesContainerFactoryException;
import org.apache.tiles.freemarker.context.FreeMarkerTilesRequestContextFactory;
import org.apache.tiles.impl.BasicTilesContainer;
import org.apache.tiles.impl.mgmt.CachingTilesContainer;
import org.apache.tiles.locale.LocaleResolver;
import org.apache.tiles.ognl.ApplicationScopeNestedObjectExtractor;
import org.apache.tiles.ognl.AnyScopePropertyAccessor;
import org.apache.tiles.ognl.DelegatePropertyAccessor;
import org.apache.tiles.ognl.NestedObjectDelegatePropertyAccessor;
import org.apache.tiles.ognl.OGNLAttributeEvaluator;
import org.apache.tiles.ognl.PropertyAccessorDelegateFactory;
import org.apache.tiles.ognl.RequestScopeNestedObjectExtractor;
import org.apache.tiles.ognl.SessionScopeNestedObjectExtractor;
import org.apache.tiles.ognl.ScopePropertyAccessor;
import org.apache.tiles.ognl.TilesApplicationContextNestedObjectExtractor;
import org.apache.tiles.ognl.TilesContextPropertyAccessorDelegateFactory;
import org.apache.tiles.renderer.AttributeRenderer;
import org.apache.tiles.renderer.TypeDetectingAttributeRenderer;
import org.apache.tiles.renderer.impl.BasicRendererFactory;
import org.apache.tiles.renderer.impl.ChainedDelegateAttributeRenderer;
import org.apache.tiles.servlet.context.ServletUtil;
import org.apache.tiles.util.URLUtil;
import org.apache.tiles.request.ApplicationContext;
import org.apache.tiles.request.ApplicationResource;
import org.apache.tiles.request.Request;
import org.apache.tiles.request.render.BasicRendererFactory;
import org.apache.tiles.request.render.ChainedDelegateRenderer;
import org.apache.tiles.request.render.Renderer;
import javax.el.ArrayELResolver;
import javax.el.BeanELResolver;
@@ -70,12 +63,11 @@ import javax.el.ELResolver;
import javax.el.ListELResolver;
import javax.el.MapELResolver;
import javax.el.ResourceBundleELResolver;
import javax.servlet.ServletContext;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
/**
* Dedicated Struts factory to build Tiles container with support for:
@@ -106,76 +98,42 @@ public class StrutsTilesContainerFactory extends BasicTilesContainerFactory {
public static final String TILES_DEFAULT_PATTERN = "tiles*.xml";
@Override
protected BasicTilesContainer instantiateContainer(TilesApplicationContext applicationContext) {
CachingTilesContainer tilesContainer = new CachingTilesContainer();
ServletContext servletContext = (ServletContext) applicationContext.getContext();
ServletUtil.setContainer(servletContext, tilesContainer);
return tilesContainer;
}
@Override
protected List<TilesRequestContextFactory> getTilesRequestContextFactoriesToBeChained(ChainedTilesRequestContextFactory parent) {
List<TilesRequestContextFactory> factories = super.getTilesRequestContextFactoriesToBeChained(parent);
registerRequestContextFactory(FreeMarkerTilesRequestContextFactory.class.getName(), factories, parent);
return factories;
public TilesContainer createDecoratedContainer(TilesContainer originalContainer, ApplicationContext applicationContext) {
return new CachingTilesContainer(originalContainer);
}
@Override
protected void registerAttributeRenderers(
BasicRendererFactory rendererFactory,
TilesApplicationContext applicationContext,
TilesRequestContextFactory contextFactory,
TilesContainer container,
AttributeEvaluatorFactory attributeEvaluatorFactory) {
final BasicRendererFactory rendererFactory,
final ApplicationContext applicationContext,
final TilesContainer container,
final AttributeEvaluatorFactory attributeEvaluatorFactory) {
super.registerAttributeRenderers(
rendererFactory,
applicationContext,
contextFactory,
container,
attributeEvaluatorFactory);
super.registerAttributeRenderers(rendererFactory, applicationContext, container, attributeEvaluatorFactory);
StrutsFreeMarkerAttributeRenderer freemarkerRenderer = new StrutsFreeMarkerAttributeRenderer();
freemarkerRenderer.setApplicationContext(applicationContext);
freemarkerRenderer.setAttributeEvaluatorFactory(attributeEvaluatorFactory);
freemarkerRenderer.setRequestContextFactory(contextFactory);
rendererFactory.registerRenderer(FREEMARKER_RENDERER_NAME, freemarkerRenderer);
}
@Override
protected AttributeRenderer createDefaultAttributeRenderer(
protected Renderer createDefaultAttributeRenderer(
BasicRendererFactory rendererFactory,
TilesApplicationContext applicationContext,
TilesRequestContextFactory contextFactory,
ApplicationContext applicationContext,
TilesContainer container,
AttributeEvaluatorFactory attributeEvaluatorFactory) {
ChainedDelegateAttributeRenderer retValue = new ChainedDelegateAttributeRenderer();
retValue.addAttributeRenderer((TypeDetectingAttributeRenderer) rendererFactory
.getRenderer(DEFINITION_RENDERER_NAME));
retValue.addAttributeRenderer((TypeDetectingAttributeRenderer) rendererFactory
.getRenderer(FREEMARKER_RENDERER_NAME));
retValue.addAttributeRenderer((TypeDetectingAttributeRenderer) rendererFactory
.getRenderer(TEMPLATE_RENDERER_NAME));
retValue.addAttributeRenderer((TypeDetectingAttributeRenderer) rendererFactory
.getRenderer(STRING_RENDERER_NAME));
retValue.setApplicationContext(applicationContext);
retValue.setRequestContextFactory(contextFactory);
retValue.setAttributeEvaluatorFactory(attributeEvaluatorFactory);
ChainedDelegateRenderer retValue = new ChainedDelegateRenderer();
retValue.addAttributeRenderer(rendererFactory.getRenderer(DEFINITION_RENDERER_NAME));
retValue.addAttributeRenderer(rendererFactory.getRenderer(FREEMARKER_RENDERER_NAME));
retValue.addAttributeRenderer(rendererFactory.getRenderer(TEMPLATE_RENDERER_NAME));
retValue.addAttributeRenderer(rendererFactory.getRenderer(STRING_RENDERER_NAME));
return retValue;
}
@Override
protected AttributeEvaluatorFactory createAttributeEvaluatorFactory(
TilesApplicationContext applicationContext,
TilesRequestContextFactory contextFactory,
ApplicationContext applicationContext,
LocaleResolver resolver) {
BasicAttributeEvaluatorFactory attributeEvaluatorFactory = new BasicAttributeEvaluatorFactory(new DirectAttributeEvaluator());
@@ -187,26 +145,30 @@ public class StrutsTilesContainerFactory extends BasicTilesContainerFactory {
@Override
protected <T> PatternDefinitionResolver<T> createPatternDefinitionResolver(Class<T> customizationKeyClass) {
DefinitionPatternMatcherFactory wildcardFactory = new WildcardDefinitionPatternMatcherFactory();
DefinitionPatternMatcherFactory regexpFactory = new RegexpDefinitionPatternMatcherFactory();
PrefixedPatternDefinitionResolver<T> resolver = new PrefixedPatternDefinitionResolver<>();
PrefixedPatternDefinitionResolver<T> resolver = new PrefixedPatternDefinitionResolver<T>();
resolver.registerDefinitionPatternMatcherFactory(PATTERN_WILDCARD, wildcardFactory);
resolver.registerDefinitionPatternMatcherFactory(PATTERN_REGEXP, regexpFactory);
resolver.registerDefinitionPatternMatcherFactory("WILDCARD", wildcardFactory);
resolver.registerDefinitionPatternMatcherFactory("REGEXP", regexpFactory);
return resolver;
}
@Override
protected List<URL> getSourceURLs(TilesApplicationContext applicationContext, TilesRequestContextFactory contextFactory) {
try {
Set<URL> finalSet = applicationContext.getResources(getTilesDefinitionPattern(applicationContext.getInitParams()));
protected List<ApplicationResource> getSources(ApplicationContext applicationContext) {
Collection<ApplicationResource> resources = applicationContext.getResources(getTilesDefinitionPattern(applicationContext.getInitParams()));
return URLUtil.getBaseTilesDefinitionURLs(finalSet);
} catch (IOException e) {
throw new DefinitionsFactoryException("Cannot load definition URLs", e);
List<ApplicationResource> filteredResources = new ArrayList<>();
if (resources != null) {
for (ApplicationResource resource : resources) {
if (Locale.ROOT.equals(resource.getLocale())) {
filteredResources.add(resource);
}
}
}
return filteredResources;
}
protected String getTilesDefinitionPattern(Map<String, String> params) {
@@ -216,55 +178,40 @@ public class StrutsTilesContainerFactory extends BasicTilesContainerFactory {
return TILES_DEFAULT_PATTERN;
}
protected ELAttributeEvaluator createELEvaluator(TilesApplicationContext applicationContext) {
protected ELAttributeEvaluator createELEvaluator(ApplicationContext applicationContext) {
ELAttributeEvaluator evaluator = new ELAttributeEvaluator();
evaluator.setApplicationContext(applicationContext);
JspExpressionFactoryFactory efFactory = new JspExpressionFactoryFactory();
efFactory.setApplicationContext(applicationContext);
evaluator.setExpressionFactory(efFactory.getExpressionFactory());
ELResolver elResolver = new CompositeELResolver() {
{
add(new TilesContextELResolver());
BeanELResolver beanElResolver = new BeanELResolver(false);
add(new ScopeELResolver());
add(new TilesContextELResolver(beanElResolver));
add(new TilesContextBeanELResolver());
add(new ArrayELResolver(false));
add(new ListELResolver(false));
add(new MapELResolver(false));
add(new ResourceBundleELResolver());
add(new BeanELResolver(false));
add(beanElResolver);
}
};
evaluator.setResolver(elResolver);
return evaluator;
}
protected OGNLAttributeEvaluator createOGNLEvaluator() {
try {
PropertyAccessor objectPropertyAccessor = OgnlRuntime.getPropertyAccessor(Object.class);
PropertyAccessor mapPropertyAccessor = OgnlRuntime.getPropertyAccessor(Map.class);
PropertyAccessor applicationContextPropertyAccessor =
new NestedObjectDelegatePropertyAccessor<>(
new TilesApplicationContextNestedObjectExtractor(),
objectPropertyAccessor);
PropertyAccessor requestScopePropertyAccessor =
new NestedObjectDelegatePropertyAccessor<>(
new RequestScopeNestedObjectExtractor(), mapPropertyAccessor);
PropertyAccessor sessionScopePropertyAccessor =
new NestedObjectDelegatePropertyAccessor<>(
new SessionScopeNestedObjectExtractor(), mapPropertyAccessor);
PropertyAccessor applicationScopePropertyAccessor =
new NestedObjectDelegatePropertyAccessor<>(
new ApplicationScopeNestedObjectExtractor(), mapPropertyAccessor);
PropertyAccessorDelegateFactory<TilesRequestContext> factory =
new TilesContextPropertyAccessorDelegateFactory(
objectPropertyAccessor, applicationContextPropertyAccessor,
requestScopePropertyAccessor, sessionScopePropertyAccessor,
applicationScopePropertyAccessor);
PropertyAccessor applicationContextPropertyAccessor = new NestedObjectDelegatePropertyAccessor<>(
new TilesApplicationContextNestedObjectExtractor(), objectPropertyAccessor);
PropertyAccessor anyScopePropertyAccessor = new AnyScopePropertyAccessor();
PropertyAccessor scopePropertyAccessor = new ScopePropertyAccessor();
PropertyAccessorDelegateFactory<Request> factory = new TilesContextPropertyAccessorDelegateFactory(
objectPropertyAccessor, applicationContextPropertyAccessor, anyScopePropertyAccessor,
scopePropertyAccessor);
PropertyAccessor tilesRequestAccessor = new DelegatePropertyAccessor<>(factory);
OgnlRuntime.setPropertyAccessor(TilesRequestContext.class, tilesRequestAccessor);
OgnlRuntime.setPropertyAccessor(Request.class, tilesRequestAccessor);
return new OGNLAttributeEvaluator();
} catch (OgnlException e) {
throw new TilesContainerFactoryException("Cannot initialize OGNL evaluator", e);
@@ -21,8 +21,8 @@ package org.apache.struts2.tiles;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tiles.TilesApplicationContext;
import org.apache.tiles.factory.AbstractTilesContainerFactory;
import org.apache.tiles.request.ApplicationContext;
import org.apache.tiles.startup.AbstractTilesInitializer;
import javax.servlet.ServletContext;
@@ -32,13 +32,13 @@ public class StrutsTilesInitializer extends AbstractTilesInitializer {
private static final Logger LOG = LogManager.getLogger(StrutsTilesInitializer.class);
@Override
protected TilesApplicationContext createTilesApplicationContext(TilesApplicationContext preliminaryContext) {
protected ApplicationContext createTilesApplicationContext(ApplicationContext preliminaryContext) {
LOG.debug("Initializing Tiles wildcard support ...");
return new StrutsWildcardServletTilesApplicationContext((ServletContext) preliminaryContext.getContext());
}
@Override
protected AbstractTilesContainerFactory createContainerFactory(TilesApplicationContext context) {
protected AbstractTilesContainerFactory createContainerFactory(ApplicationContext context) {
LOG.trace("Creating dedicated Struts factory to create Tiles container");
return new StrutsTilesContainerFactory();
}
@@ -24,20 +24,24 @@ import com.opensymphony.xwork2.util.WildcardUtil;
import com.opensymphony.xwork2.util.finder.ResourceFinder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tiles.servlet.context.ServletTilesApplicationContext;
import org.apache.logging.log4j.message.MessageFormatMessage;
import org.apache.tiles.request.ApplicationResource;
import org.apache.tiles.request.locale.URLApplicationResource;
import org.apache.tiles.request.servlet.ServletApplicationContext;
import javax.servlet.ServletContext;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
public class StrutsWildcardServletTilesApplicationContext extends ServletTilesApplicationContext {
public class StrutsWildcardServletTilesApplicationContext extends ServletApplicationContext {
private static final Logger LOG = LogManager.getLogger(StrutsWildcardServletTilesApplicationContext.class);
@@ -70,36 +74,42 @@ public class StrutsWildcardServletTilesApplicationContext extends ServletTilesAp
finder = new ResourceFinder(urls.toArray(new URL[urls.size()]));
}
public Set<URL> getResources(String path) throws IOException {
Set<URL> resources = new HashSet<>();
public Collection<ApplicationResource> getResources(String path) {
Set<ApplicationResource> resources = new HashSet<>();
if (path.startsWith("/")) {
LOG.trace("Using ServletContext to load resource #0", path);
URL resource = getResource(path);
LOG.trace("Using ServletContext to load resource {}", path);
ApplicationResource resource = getResource(path);
if (resource != null) {
resources.add(resource);
}
}
resources.addAll(findResources(path));
try {
resources.addAll(findResources(path));
} catch (IOException e) {
LOG.error(new MessageFormatMessage("Cannot find resources for [{}]", path), e);
}
return resources;
}
protected Set<URL> findResources(String path) throws IOException {
Set<URL> resources = new HashSet<>();
protected Set<ApplicationResource> findResources(String path) throws IOException {
Set<ApplicationResource> resources = new HashSet<>();
LOG.trace("Using ResourceFinder to find matches for #0", path);
LOG.trace("Using ResourceFinder to find matches for {}", path);
Pattern pattern = WildcardUtil.compileWildcardPattern(path);
Map<String, URL> matches = finder.getResourcesMap("");
for (String resource : matches.keySet()) {
if (pattern.matcher(resource).matches()) {
resources.add(matches.get(resource));
URL url = matches.get(resource);
resources.add(new URLApplicationResource("", url));
}
}
LOG.trace("Found resources #0 for path #1", resources, path);
LOG.trace("Found resources {} for path {}", resources, path);
return resources;
}