struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Lukasz Lenart <lukaszlen...@apache.org>
Subject Re: Limitations using Struts2-conventions-plugin (lack of multiple configuration roots)
Date Mon, 10 Jul 2017 08:07:14 GMT
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.mcwilliams@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 <lukaszlenart@apache.org>
> wrote:
>
>> 2017-06-22 2:45 GMT+02:00 Ken McWilliams <ken.mcwilliams@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-unsubscribe@struts.apache.org
>> For additional commands, e-mail: user-help@struts.apache.org
>>
>>
>
>
> --
> Sent from my C64 using a 300 baud modem

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Mime
View raw message