Thank you for meditating on this! On Mon, Jul 10, 2017 at 2:07 AM, Lukasz Lenart <lukaszlen...@apache.org> wrote:
> I thought about this idea and it requires implementation of a root > Dispatcher with list of child Dispatchers per config file/package/etc. > Doable but won't happen soon ;-) > > 2017-06-23 23:22 GMT+02:00 Ken McWilliams <ken.mcwilli...@gmail.com>: > > Yes, something like that. > > > > But I think i can be done in a hackish way without much change. Really it > > is the conventions plugin that is at fault, or rather a lack of > convention > > regarding sharing configuration that aught to be standardized. > > > > The beans and constants are currently scoped globally, just inside the > > <struts></struts> the beans in struts2-conventions-plugin > struts-plugin.xml > > file can only be set once. > > > > Consider the struts2-rest plugin, at a quick glance of the setup > > documentation it is clear that it wants to impose it's own conventions: > > https://cwiki.apache.org/confluence/display/WW/REST+Plugin you will see > a > > number of blocks such as: > > > > <constant name="struts.convention.action.suffix" value="Controller"/> > > <constant name="struts.convention.action.mapAllMatches" value="true"/> > > <constant name="struts.convention.default.parent.package" value= > > "rest-default"/> > > <constant name="struts.convention.package.locators" value="example"/> > > > > Which are required in the setup. This isn't as simple as it aught to be, > > there should be a number of packages defined in the rest plugins > > struts-plugin.xml and by extending that get the most typical > configurations > > (obviously every configuration can't be known but a couple choices > wouldn't > > be bad). Is it reasonable for people to be intimately familiar with the > > conventions configuration such that they would know how to configure the > > rest plugin? As it stands this seems to be the case but in terms of user > > experience, it's a bit of a pain and if you want both your conventions > AND > > the rest plugin, you find yourself being stuck (like an under-inflated > > balloon animal, you can choose to have the head inflated of the tail, but > > not both). > > > > This is one possible way to solve the issue: > > - Create a new interceptor called "PackageConfigurationInterceptor"; > since > > interceptors are instantiated once per package they have the scope that I > > would expect. > > - When using conventions scan for the existence of this interceptor, if > > found use it's beans and constants in place of the global ones. > > > > ======================================= > > package com.kenmcwilliams.struts.config; > > > > public class ConventionsPackageConfigInterceptor extends > > PackageConfigInterceptor { > > > > public ConventionsPackageConfigInterceptor() { > > super(); > > // <bean type="com.opensymphony.xwork2.UnknownHandler" > > name="convention" > > class="org.apache.struts2.convention.ConventionUnknownHandler"/> > > this.beans.add(new > > StrutsBean("com.opensymphony.xwork2.UnknownHandler", "convention", > > "org.apache.struts2.convention.ConventionUnknownHandler")); > > > > // <bean type="org.apache.struts2.convention.ActionConfigBuilder" > > name="convention" > > class="org.apache.struts2.convention.PackageBasedActionConfigBuilder"/> > > // <bean type="org.apache.struts2.convention.ActionNameBuilder" > > name="convention" > > class="org.apache.struts2.convention.SEOActionNameBuilder"/> > > // <bean type="org.apache.struts2.convention.ResultMapBuilder" > > name="convention" > > class="org.apache.struts2.convention.DefaultResultMapBuilder"/> > > // <bean type="org.apache.struts2.convention.InterceptorMapBuilder" > > name="convention" > > class="org.apache.struts2.convention.DefaultInterceptorMapBuilder"/> > > // <bean type="org.apache.struts2.convention.ConventionsService" > > name="convention" > > class="org.apache.struts2.convention.ConventionsServiceImpl"/> > > this.beans.add(new > > StrutsBean("org.apache.struts2.convention.ActionConfigBuilder", > > "convention", > > "org.apache.struts2.convention.PackageBasedActionConfigBuilder")); > > this.beans.add(new > > StrutsBean("org.apache.struts2.convention.ActionNameBuilder", > "convention", > > "org.apache.struts2.convention.SEOActionNameBuilder")); > > this.beans.add(new > > StrutsBean("org.apache.struts2.convention.ResultMapBuilder", > "convention", > > "org.apache.struts2.convention.DefaultResultMapBuilder")); > > this.beans.add(new > > StrutsBean("org.apache.struts2.convention.InterceptorMapBuilder", > > "convention", > > "org.apache.struts2.convention.DefaultInterceptorMapBuilder")); > > this.beans.add(new > > StrutsBean("org.apache.struts2.convention.ConventionsService", > > "convention", "org.apache.struts2.convention.ConventionsServiceImpl")); > > // <bean type="com.opensymphony.xwork2.config.PackageProvider" > > name="convention.packageProvider" > > class="org.apache.struts2.convention.ClasspathPackageProvider"/> > > // <bean type="com.opensymphony.xwork2.config.PackageProvider" > > name="convention.containerProvider" > > class="org.apache.struts2.convention.ClasspathConfigurationProvider"/> > > // > > this.beans.add(new > > StrutsBean("com.opensymphony.xwork2.config.PackageProvider", > > "convention.packageProvider", > > "org.apache.struts2.convention.ClasspathPackageProvider")); > > this.beans.add(new > > StrutsBean("com.opensymphony.xwork2.config.PackageProvider", > > "convention.packageProvider", > > "org.apache.struts2.convention.ClasspathConfigurationProvider")); > > > > // <constant name="struts.convention.actionConfigBuilder" > > value="convention"/> > > // <constant name="struts.convention.actionNameBuilder" > > value="convention"/> > > // <constant name="struts.convention.resultMapBuilder" > value="convention"/> > > // <constant name="struts.convention.interceptorMapBuilder" > > value="convention"/> > > // <constant name="struts.convention.conventionsService" > > value="convention"/> > > this.constants.add(new > > StrutsConstant("struts.convention.actionConfigBuilder", "convention")); > > this.constants.add(new > > StrutsConstant("struts.convention.actionNameBuilder", "convention")); > > this.constants.add(new > > StrutsConstant("struts.convention.resultMapBuilder", "convention")); > > this.constants.add(new > > StrutsConstant("struts.convention.interceptorMapBuilder", > "convention")); > > this.constants.add(new > > StrutsConstant("struts.convention.conventionsService", "convention")); > > // <constant name="struts.convention.result.path" > > value="/WEB-INF/content/"/> > > // <constant name="struts.convention.result.flatLayout" value="true"/> > > // <constant name="struts.convention.action.suffix" value="Action"/> > > // <constant name="struts.convention.action.disableScanning" > > value="false"/> > > // <constant name="struts.convention.action.mapAllMatches" > value="false"/> > > // <constant name="struts.convention.action.checkImplementsAction" > > value="true"/> > > // <constant name="struts.convention.default.parent.package" > > value="convention-default"/> > > // <constant name="struts.convention.action.name.lowercase" > value="true"/> > > // <constant name="struts.convention.action.name.separator" value="-"/> > > // <constant name="struts.convention.package.locators" > > value="action,actions,struts,struts2"/> > > // <constant name="struts.convention.package.locators.disable" > > value="false"/> > > // <constant name="struts.convention.package.locators.basePackage" > > value=""/> > > // <constant name="struts.convention.exclude.packages" > > value="org.apache.struts.*,org.apache.struts2.*,org. > springframework.web.struts.*,org.springframework.web. > struts2.*,org.hibernate.*"/> > > // <constant name="struts.convention.relative.result.types" > > value="dispatcher,velocity,freemarker"/> > > // <constant name="struts.convention.redirect.to.slash" value="true"/> > > // <constant name="struts.convention.action.alwaysMapExecute" > > value="true"/> > > // <constant name="struts.mapper.alwaysSelectFullNamespace" > value="true"/> > > // <!-- <constant name="struts.convention.action.includeJars" /> --> > > // <constant name="struts.convention.action.fileProtocols" value="jar" > /> > > > > this.constants.add(new > > StrutsConstant("struts.convention.result.path", "/WEB-INF/content/")); > > this.constants.add(new > > StrutsConstant("struts.convention.result.flatLayout", "true")); > > this.constants.add(new > > StrutsConstant("struts.convention.action.suffix", "Action")); > > this.constants.add(new > > StrutsConstant("struts.convention.action.disableScanning", "false")); > > this.constants.add(new > > StrutsConstant("struts.convention.action.mapAllMatches", "false")); > > this.constants.add(new > > StrutsConstant("struts.convention.action.checkImplementsAction", > "true")); > > this.constants.add(new > > StrutsConstant("struts.convention.default.parent.package", > > "convention-default")); > > this.constants.add(new > > StrutsConstant("struts.convention.action.name.lowercase", "true")); > > this.constants.add(new > > StrutsConstant("struts.convention.action.name.separator", "-")); > > this.constants.add(new > > StrutsConstant("struts.convention.package.locators", > > "action,actions,struts,struts2")); > > this.constants.add(new > > StrutsConstant("struts.convention.package.locators.disable", "false")); > > this.constants.add(new > > StrutsConstant("struts.convention.package.locators.basePackage", "")); > > this.constants.add(new > > StrutsConstant("struts.convention.exclude.packages", > > "org.apache.struts.*,org.apache.struts2.*,org. > springframework.web.struts.*,org.springframework.web. > struts2.*,org.hibernate.*")); > > this.constants.add(new > > StrutsConstant("struts.convention.relative.result.types", > > "dispatcher,velocity,freemarker")); > > this.constants.add(new > > StrutsConstant("struts.convention.redirect.to.slash", "true")); > > this.constants.add(new > > StrutsConstant("struts.convention.action.alwaysMapExecute", "true")); > > this.constants.add(new > > StrutsConstant("struts.mapper.alwaysSelectFullNamespace", "true")); > > this.constants.add(new > > StrutsConstant("struts.convention.action.fileProtocols", "jar")); > > > > // <constant name="struts.convention.classes.reload" value="false" /> > > this.constants.add(new > > StrutsConstant("struts.convention.classes.reload", "false")); > > // <constant name="struts.convention.exclude.parentClassLoader" > > value="true" /> > > this.constants.add(new > > StrutsConstant("struts.convention.exclude.parentClassLoader", "true")); > > } > > } > > > > ======================================= > > > > package com.kenmcwilliams.struts.config; > > > > import com.opensymphony.xwork2.ActionInvocation; > > import com.opensymphony.xwork2.interceptor.Interceptor; > > import java.util.ArrayList; > > import java.util.HashSet; > > import java.util.Iterator; > > import java.util.List; > > import java.util.Optional; > > > > /** > > * One instance of an interceptor is created per struts-package > > * @author ken > > */ > > public class PackageConfigInterceptor implements Interceptor{ > > public final HashSet<StrutsConstant> constants = new HashSet(); > > public final List<StrutsBean> beans = new ArrayList(); > > > > public List<StrutsBean> findBean(String name, String type){ > > List<StrutsBean> found = new ArrayList(); > > for(StrutsBean bean : beans){ > > if(bean.getName().equals(name) && > bean.getType().equals(type)){ > > found.add(bean); > > } > > } > > return found; > > } > > > > public Optional<StrutsConstant> findConstant(String name){ > > Iterator<StrutsConstant> iterator = this.constants.iterator(); > > while(iterator.hasNext()){ > > StrutsConstant constant = iterator.next(); > > if(constant.getName().equals(name)){ > > return Optional.of(constant); > > } > > } > > return Optional.ofNullable(null); > > } > > > > @Override > > public void destroy() { > > } > > > > @Override > > public void init() { > > > > } > > > > @Override > > public String intercept(ActionInvocation invocation) throws > Exception { > > return invocation.invoke(); > > } > > } > > > > ======================================= > > > > The above was just a quick hack for illustration. If struts could extend > > it's configuration and xml to provide package level scope (struts > packages) > > and object for such purposes, and some functionality to provide > > configuration lookup from the perspective of a particular package a less > > hackish/reflective hoop-jumping could be done when reimplementing the > > conventions plugin, as it stands it's probably possible using this > > interceptor technique. > > > > > > > > > > > > > > On Fri, Jun 23, 2017 at 12:39 AM, Lukasz Lenart <lukaszlen...@apache.org > > > > wrote: > > > >> 2017-06-22 2:45 GMT+02:00 Ken McWilliams <ken.mcwilli...@gmail.com>: > >> > Sure, doing Struts2/Shiro integration at the moment. Will come back to > >> > this, it was a rant from running into issues when setting up some > >> personal > >> > demo projects. The limitation from one static configuration to cover > all > >> > conventions (which really just lets you use one convention, at least > >> well). > >> > >> Did I get this right, you want to have multiple configuration in the > >> same app, like having multiple struts.xml files in one app, right? > >> Hmm... maybe it is doable ... per a root package .... > >> > >> > >> Regards > >> -- > >> Ćukasz > >> + 48 606 323 122 http://www.lenart.org.pl/ > >> > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail: user-unsubscr...@struts.apache.org > >> For additional commands, e-mail: user-h...@struts.apache.org > >> > >> > > > > > > -- > > Sent from my C64 using a 300 baud modem > > --------------------------------------------------------------------- > To unsubscribe, e-mail: user-unsubscr...@struts.apache.org > For additional commands, e-mail: user-h...@struts.apache.org > > -- Sent from my C64 using a 300 baud modem