Yes, you can do that.  But I prefer not to have to modify Application when I
add a new page.  With an annotation-based approach, I define a page,
annotate it and then I'm done.

Really, this is just a philosophical difference.  Rather than argue which is
better, we could offer both. Annotation usage is a matter of preference. 
Some people will want to use it; others not.  Adding mounts in the
application init() method may make more sense for some applications than
others.  In my application, I think using annotations is much simpler.

The code I have is working and is pretty non-invasive change to
WebRequestCodingStrategy (see below for how I did it via subclassing).  I
need to get Wicket building in my environment so I can figure out where to
put the annotation classes so I can submit a patch.

-Doug

public class AnnotationAwareWebRequestCodingStrategy extends
WebRequestCodingStrategy
{
    @Override
    protected IRequestTargetUrlCodingStrategy getMountEncoder(IRequestTarget
requestTarget)
    {
        IRequestTargetUrlCodingStrategy strategy =
super.getMountEncoder(requestTarget);

        // if no strategy found, see if there is one we can create via
annotations
        if (strategy == null)
        {
            strategy = getAnnotatedMountEncoder(requestTarget);
            if (strategy != null)
            {
                mount(strategy);
            }
        }
        return strategy;
    }

    protected IRequestTargetUrlCodingStrategy
getAnnotatedMountEncoder(IRequestTarget requestTarget)
    {
        IRequestTargetUrlCodingStrategy strategy = null;

        // If this is a bookmarkable page reqeuest, see if it has a mount
annotation
        if (requestTarget instanceof IBookmarkablePageRequestTarget)
        {
            // Look for @MountPath annotation on the page class
            IBookmarkablePageRequestTarget target =
(IBookmarkablePageRequestTarget)requestTarget;
            Class<? extends Page> pageClass = target.getPageClass(); // FIX:
this may change in Wicket 1.4
            strategy = getAnnotatedMountEncoder(pageClass);
        }
        return strategy;
    }

    protected IRequestTargetUrlCodingStrategy
getAnnotatedMountEncoder(Class<? extends Page> pageClass)
    {
        // ... meat of the code here ...
    }


igor.vaynberg wrote:
> 
> i prefer a simple factory method on pages that construct
> pageparameters or even an entire bookmarkable page link...
> 
> PageParameters params=Leaderboard.newPageParameters(someType, someDays);
> add(new BookmarkablePageLink("id", Leaderboard.class, params));
> 
> or just
> 
> add(Leaderboard.newBookmarkableLink("id", someType, someDays));
> 
> encapsulation without all the overhead of annots, etc
> 
> -igor
> 
> 
> On Sat, May 3, 2008 at 2:25 PM, Doug Donohoe <[EMAIL PROTECTED]> wrote:
>>
>>  One thing that is valuable is encapsulation.  For example, take my
>>  Leaderboard class which has two main inputs via PageParameters:
>>
>>
>>
>>     static final String PARAM_TYPE = "type";
>>     static final String PARAM_DAYS = "days";
>>
>>  Now, using the current metaphor, I when I want to mount using a
>> MixedParam
>>  strategy, I have to (a) expose these as public and (b) then add code in
>> my
>>  init() method like:
>>
>>     mount(new MixedParamUrlCodingStrategy("leaderboard",
>> Leaderboard.class,
>>               new String { Leaderboard.PARAM_TYPE,
>> Leaderboard.PARAM_DAYS});
>>
>>  I'm exposing information I don't really want to.  Instead, why I'm doing
>> now
>>  is:
>>
>>     @MountPath(path = "leaderboard")
>>     @MountMixedParam(parameterNames = {Leaderboard.PARAM_TYPE,
>>  Leaderboard.PARAM_DAYS})
>>     public class Leaderboard extends WebPage { ... }
>>
>>  If I add or change the PARAMS, I only have to change Leaderboard - it
>>  controls how it is mounted rather than up at the Application level.
>>
>>  If somebody else wants to use this page and change the mount point, they
>> can
>>  subclass:
>>
>>     @MountPath(path = "my/leaderboard")
>>     public class MyLeaderboard extend Leaderboard
>>
>>  The @MountMixedParam annotation is inherited wherea the @MountPath is
>> not.
>>  I haven't tested this yet (I'll add it to my unit test), but you could
>> also
>>  specify a different mount strategy than MixedParam if you wanted to
>> override
>>  that.
>>
>>  If a class is not annotated with @MountPath, it is not mountable (via
>>  annotations).
>>
>>  If you just define @MountPath and no supporting annotation, it defaults
>> to
>>  BookmarkablePage...Strategy.
>>
>>  Regarding multiple mounts, I could add that by making path a string
>> array -
>>  I wasn't sure how often that was used because the way
>>  WebRequestCodingStrategy.getMountEncoder works is that it picks the
>> first
>>  one it finds (when mapping a class to a mount path).
>>
>>  For the curious, @MountMixedParam is defined as follows:
>>
>>     @Target({ ElementType.TYPE })
>>     @Retention(RetentionPolicy.RUNTIME)
>>     @MountDefinition(strategyClass = MixedParamUrlCodingStrategy.class,
>>  argOrder = {"pageMapName", "parameterNames"})
>>     @Inherited
>>     @Documented
>>     public @interface MountFixedMixedParam
>>     {
>>         String pageMapName() default MountDefinition.NULL;
>>
>>         String[] parameterNames();
>>     }
>>
>>  This basically defines how to construct the mount strategy class and
>> what
>>  the params are.  One of these would need to be defined for each of the
>>  half-dozen or so UrlCodingStrategies.  We could make them inner
>> interfaces
>>  to keep the definition with the class.
>>
>>  Note that this mechanism allows for easy extension by end-users.
>>
>>  I'm using this in my site and it is quite nice.
>>
>>  I'll post more details later - I'm still testing, etc.
>>
>>  -Doug
>>
>>
>>  Johan Compagner wrote:
>>  >
>>  > personally i dont see any added value.
>>  > It is stil a line of "code", no gain here.
>>  > then scattered throughout your code base
>>  > also you have to make sure that you can have then multiply of those
>> mounts
>>  > for 1 class
>>  > i use the same pages under different mounts..
>>  >
>>  > also what happens if you package your pages and somebody else uses it
>>  > or you start to also use them in an other project...
>>  > But that doesnt want those mount points... what then? you cant remove
>> them
>>  > because then the first app breaks...
>>  > I still think mounting and stuff is something the Application is
>>  > responsible
>>  > for not the web app itself.
>>  >
>>  > I could see an annotation like: @Unmountable ...
>>  > Because it is sort of a security hole in wicket now. If a page has a
>>  > default
>>  > constructor and i know the name i could just show it... (of no other
>>  > security prevents that)
>>  > Ofcourse this is very hypothetical and not very likely that it will be
>>  > abused because you have to know classnames (but these can spoil out
>> when
>>  > not
>>  > carefull with shared resouces..)
>>  >
>>  >
>>  > johan
>>  >
>>  >
>>
>>  --
>>  View this message in context:
>> http://www.nabble.com/how-to-contribute---wicket-1.4-plans-tp17034501p17039998.html
>>  Sent from the Wicket - Dev mailing list archive at Nabble.com.
>>
>>
> 
> 

-- 
View this message in context: 
http://www.nabble.com/how-to-contribute---wicket-1.4-plans-tp17034501p17040515.html
Sent from the Wicket - Dev mailing list archive at Nabble.com.

Reply via email to