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