struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ken McWilliams <ken.mcwilli...@gmail.com>
Subject Re: Limitations using Struts2-conventions-plugin (lack of multiple configuration roots)
Date Wed, 12 Jul 2017 18:51:59 GMT
Thank you for meditating on this!

On Mon, Jul 10, 2017 at 2:07 AM, Lukasz Lenart <lukaszlenart@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.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
>
>


-- 
Sent from my C64 using a 300 baud modem

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message