Hi Jason,

The general approach sounds good. A large part of the NMaven project deals
with matching of platform capabilities. The pattern includes:

public interface ExecutableMatchPolicy
{

   /**
    * Returns true if <code>ExecutableCapability</code> matches the policy
implementation, otherwise returns false.
    *
    * @param executableCapability the executable capability to match
    * @return true if <code>ExecutableCapability</code> matches the policy
implementation, otherwise returns false.
    */
   boolean match( ExecutableCapability executableCapability );
}
with an implementation like this within a Factory class. This one matches
version.

   /**
    * Creates a policy to match the framework version
    *
    * @param frameworkVersion
    * @return a policy to match the framework version
    */
   static ExecutableMatchPolicy createFrameworkVersionPolicy( final String
frameworkVersion )
   {
       return new ExecutableMatchPolicy()
       {
           public boolean match( ExecutableCapability executableCapability
)
           {
               for ( String fv : executableCapability.getFrameworkVersions()
)
               {
                   if ( frameworkVersion.toLowerCase().trim().equals(
fv.trim() ) )
                   {
                       return true;
                   }
               }
               return false;
           }
       };
   }

Next, a class that contains iterating over a list of match policies, meaning
all policies must be true for a match:

   private boolean matchExecutableCapability( ExecutableCapability
executableCapability,
                                              List<ExecutableMatchPolicy>
matchPolicies )
   {
       for ( ExecutableMatchPolicy executableMatchPolicy : matchPolicies )
       {
           boolean match = executableMatchPolicy.match(
executableCapability );
           if ( !match )
           {
               return false;
           }
       }
       return true;
   }

Hope this help,
Shane

On 3/21/07, Jason Dillon <[EMAIL PROTECTED]> wrote:

Hey, this occurred to me last night...

Why not have one goal, enforcer:enforce, then abstract the things to
enforce into rules...

public interface EnforcementRule {
    void execute();
}

And then configure...

<plugin>
    <groupId>...
    <artifactId>...
    <configuration>
        <rules>
            <requireJavaVersion>
                <version>[1.3,1.6]</version>
            </requireJavaVersion>
            <requireMavenVersion>
                <version>[2.0.5)</version>
            </requireMavenVersion>
        </rules>
    </configuration>
</plugin>

IIUC if have 'EnforcementRule[] rules;' in your mojo and you define
impls of EnforcementRule like RequireJavaVersion and
RequireMavenVersion in the same package, then plexus should inject
the instances of the right class into the array.

Then the mojo is really simple, can execute any kind of rules from
it... and folks can use the implementation="" stuff to inject their
own rules too if needed.  Then the goal basically executes the rules
and then based on if they pass/fail do something about it (fail the
build, warn, etc.).

--jason


On Mar 20, 2007, at 4:19 PM, Brian E. Fox wrote:

>
>
>
>> Personally I have not problem adding extra execution per thing
>> I want to enforce.  IMO that is much clearer and simplifies
>> the implementing mojo.
>
> Potentially yes, but it's also a performance issue invoking the plugin
> extra times. In my situation, I have about 100+ modules that would be
> doing this. If I can figure out how to make it execute only once per
> execution no matter where the build is started, then I think
> separating
> them is logical. In fact, if this is possible, I think it's a
> requirement.
>
>
>> Funny... most folks I know don't use version ranges.  We
>> (geronimo) tried to use them at one point for our specs, but
>> key plugins (like the idea plugin) don't support it.
>
>> I don't think that most folks using M2 are familiar with
>> ranges...  nor do they use them... and when those who do use
>> them... usually tend to find out they don't work so well.
>
> Fair enough. I think I discovered why they don't work in many cases
> while trying to use them.
>
>> The OS stuff falls into the same boat, why reinvent a syntax when one
>> already exists?
>
>> Ya, I hear ya... it was just a comment... and more about how
>> the range syntax hurts my brain more than anything ;-)  Just
>> looking at a range its not really easy to tell what it
>> means... where IMO the 1.0+ and 1.0* syntax is relatively
>> clear w/o having to go read a syntax mapping table ;-)
>
> Although I am not a fan of the implementation, the syntax is logical
> once you understand it. Not entirely covering all scenarios, but
> certainly enough for this. I don't think the 1.0+, 1.0* is enough to
> handle all cases.
>
> Consider 2.1. Perhaps there is a regression in backwards compatibility
> in the first build. Someone may want to say 2.0.6 < x < 2.1 || x > 2.1
> (in otherwords greater than 2.0.6 but not 2.1.0. You can do this with
> the current specification. I'm not sure that any expression
> language is
> going to be completely natural and support enough use cases... If
> that's
> true, then this one is as good as any. I could be convinced otherwise
> though if there are some alternatives that can be pointed out.
>
> Does anyone else have an opinion?
>
> (btw, I anticipated exactly this disussion, which is why I put out the
> RFC)
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>


Reply via email to