dev@jersey.java.net

Re: URI resolving going forward

From: Frank Martínez <mnesarco_at_gmail.com>
Date: Mon, 19 Nov 2007 12:31:17 -0500

Hi Paul,
I think the easier path is that you implement it before with your
Linear Matching implementation.
Then i follow you with the automata implementation based on your code.
What do you think about this?

Frank.

On Nov 19, 2007 12:00 PM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
> Hi Frank,
>
> Now that you have updated things to the rules SPI we can now start work
> separating URI template from the URI rules.
>
> I have created a UriPattern class. The plan is to simplify
> UriTemplateType to use this and return an associated instance. Then the
> runtime model can modify by tacking on terminating capturing groups as
> required by the URI template annotation. The runtime model should also
> be responsible for ordering. That way how things are ordered and how the
> patterns are generated are independent from the UriRules and UriRule
> implementations.
>
> Perhaps the trickiest thing for the automata matching implementation is
> processing the regular expression (previously it was bound to the
> template syntax). I thought about creating a regex simple model but now
> that seems a little over the top, since this is really a restriction
> with the automata implementation, namely, it supports a limited regular
> expression syntax (that which is generated from the URI templates
> according to the 311 spec).
>
> Paul.
>
>
>
> Frank Martínez wrote:
> > Hi Paul,
> > Everything sounds great. I will start working on it tomorrow night.
> > It must be easy now.
> >
> > Frank.
> >
> > On Nov 13, 2007 5:29 PM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
> >> Hi Frank,
> >>
> >> I have completed converting over to the new rules/rule match/accept
> >> interfaces and impls in the branch. All unit tests pass, so it has fixed
> >> that rather tricky bug of matching sub-methods with the same regexs but
> >> with different template names. The end result is i think much cleaner
> >> and more adaptable.
> >>
> >> It should be fairly easy to convert the TrieUriPathResolver to say an
> >> 'AutomataMatchingUriTemplateRules' in the com.sun.ws.rest.impl.uri.rules
> >> package, see the LinearMatchingUriTemplateRules. A test can be added by
> >> copying the class LinearMatchingTest.
> >>
> >> For now we can keep it to just zero or at most one match, like the
> >> linear algorithm. Notice that there is no need to support a map of
> >> template name to values or the right hand path (since this is just the
> >> last optional capturing group, either '(/.*)?' or '(/)?'), so just a
> >> list for the capturing group values is required. Not sure if this
> >> simplifies things, i notice you are currently depending URI template
> >> match functionality to refine the matching and get the template values,
> >> perhaps when modified this is no longer required?
> >>
> >> In any case we can start working on separating UriTemplateType from the
> >> automata implementation by creating a simple regex model of a simple
> >> regular expression. Such instances would be generated from the URI
> >> template and additional runtime information like the @UriTemplate value
> >> limited, or for supporting distinct URLs, for example ending in ".xml"
> >> or ".json". The end result should be that UriRules implementations are
> >> independent of the context of the patterns that have been created.
> >>
> >> Actually it just occurred to me that we can simplify the UriRules
> >> instance and remove the 'add' and 'getRules' methods, these can be part
> >> of an abstract class. That way it should be possible to initialize
> >> things correctly without having to rely on synchronization logic as you
> >> currently require. I will wait until things have been converted over
> >> before making this change.
> >>
> >> Paul.
> >>
> >>
> >> Paul Sandoz wrote:
> >>> Hi,
> >>>
> >>> Below are proposed interfaces for abstracting out URI path processing
> >>> along lines similar to Phobos.
> >>>
> >>> The basic looping is as follows:
> >>>
> >>> RuleContext c = ...
> >>> Rules rules = ...
> >>> Iterator<Rule> i = rules.match(path, c)
> >>> while (i.hasNext()) {
> >>> if (i.next().accept(path, c))
> >>> break;
> >>>
> >>> or:
> >>>
> >>> RuleContext c = ...
> >>> Rules rules = ...
> >>> for (Rule rule : rules.match(path, c))
> >>> if (rule.accept(path, c))
> >>> break;
> >>>
> >>> This should enable matching optimization implementations, and a
> >>> separation of a list of matching groups of a regex generated from an
> >>> associated URI template (if any association).
> >>>
> >>> The efficient automaton algorithm works from limited regex expressions
> >>> produced from the UriTemplateType. I think we can separate out the two
> >>> by having a Regex class that provides a model (or complex regexes for
> >>> other cases) produced from a URI template and the runtime. This should
> >>> also enable us to better generate and support simple regexes for
> >>> distinct URI matching that are generated from a canonical URI template.
> >>>
> >>> Paul.
> >>>
> >>> /**
> >>> * A rule, which operates on a URI path.
> >>> *
> >>> * @author Paul.Sandoz_at_Sun.Com
> >>> */
> >>> public interface Rule {
> >>> /**
> >>> * Accept the rule.
> >>> *
> >>> * @param path the URI path
> >>> * @param context the rule context
> >>> * @return if true then the rule was accepted,
> >>> * otherwise if false then the rule was
> >>> * not accepted.
> >>> */
> >>> boolean accept(String path, RuleContext context);
> >>> }
> >>>
> >>> /**
> >>> * An ordered collections of rules.
> >>> * <p>
> >>> * Each rule is associated with a regular expression.
> >>> * <p>
> >>> * The collection of rules are matched against a URI path.
> >>> *
> >>> * @author Paul.Sandoz_at_Sun.Com
> >>> */
> >>> public interface Rules {
> >>> /**
> >>> * Add a rule to the end of the collection of existing rules,
> >>> * and associate the rule with a regular expression.
> >>> *
> >>> * @param r, the rule associated with the regular expression.
> >>> * @param regex, the regular expression to be used to matched.
> >>> */
> >>> void add(Rule r, Regex regex);
> >>>
> >>> /**
> >>> * Iterate over the available matching rules.
> >>> *
> >>> * @param path, the URI path to be matched
> >>> * @param context the rule context
> >>> * @return an iterator of matching rules
> >>> */
> >>> Iterator<Rule> match(String path, RuleContext c);
> >>> }
> >>>
> >>> /**
> >>> *
> >>> * @author Paul.Sandoz_at_Sun.Com
> >>> */
> >>> public interface RuleContext {
> >>>
> >>> HttpContextAccess getHttpContext();
> >>>
> >>> HttpRequestContext getHttpRequestContext();
> >>>
> >>> HttpResponseContext getHttpResponseContext();
> >>>
> >>> /**
> >>> * Match and accept the sub rules associated with a class.
> >>> *
> >>> */
> >>> boolean subRules(Class nodeClass, StringBuilder path);
> >>>
> >>> /**
> >>> * Match and accept the sub rules associated with an object.
> >>> *
> >>> */
> >>> boolean subRules(Object node, StringBuilder path);
> >>>
> >>> List<String> getMatchingGroups();
> >>> }
> >>>
> >>> Paul Sandoz wrote:
> >>>> Hi,
> >>>>
> >>>> Below are the proposed steps going forward for URI path resolving:
> >>>>
> >>>> 1) Change URI path resolving to work from a simple regular expression
> >>>> model (generated from a URI template or otherwise). This is so we can
> >>>> fix issue 1 [1] and can easily support distinct URIs with suffixes
> >>>> associated with media type, language etc that we have been discussing
> >>>> in the EG.
> >>>>
> >>>> 2) Integrate the automaton (trie) resolver into the trunk (keeping the
> >>>> linear resolver in the trunk too for backup, perhaps we should have a
> >>>> runtime option on which to use?) and ensure it works with changes
> >>>> introduced for 1).
> >>>>
> >>>> 3) Change URI path resolving to the same model as Phobos. I have been
> >>>> talking with Roberto (the Phobos guy) and he convinced me that the
> >>>> model Phobos uses is more flexible than what Jersey currently has and
> >>>> should result in more simplicity when we need to add more features.
> >>>> Basically Phobos has a list of rules, each rule contains a regular
> >>>> expression and an accepting function. The basic algorithm is as
> >>>> follows:
> >>>>
> >>>> for rule in rules:
> >>>> if rule.regexp.match(url) and rule.accept(url):
> >>>> break
> >>>>
> >>>> So a match is just the first stage from which the rule can decide
> >>>> whether it accepts the match or whether matching should continue.
> >>>>
> >>>> This allows us to have the following rules associated with a resource
> >>>> class:
> >>>>
> >>>> - a head rule to dynamically detect view templates (like JSPs or
> >>>> Velocity templates) for a resource class that are not explicitly
> >>>> declared on the resource class. Same goes for static content;
> >>>>
> >>>> - two resource classes with the same URIs but supporting different
> >>>> representations e.g. implement XML then implement Atom without
> >>>> changing existing code. The first could return a not acceptable
> >>>> response and therefore it is a non-accepting rule and it passes it
> >>>> over to the next one; and
> >>>>
> >>>> - return a customized 404 response. A tail rule could return a
> >>>> particular 404 response (or any other error-based response) for a
> >>>> resource class.
> >>>>
> >>>>
> >>>> To ensure existing code works we can integrate the UriPathResolver as
> >>>> one rule. That way the trie algorithm will still work and then we
> >>>> can think how to transition it over to a more general rule based
> >>>> implementation.
> >>>>
> >>>>
> >>>> Sound like a plan? Any opinions either way on this approach?
> >>>>
> >>>> Paul.
> >>>>
> >>>> [1] https://jersey.dev.java.net/issues/show_bug.cgi?id=1
> >>>>
> >> --
> >> | ? + ? = To question
> >> ----------------\
> >> Paul Sandoz
> >> x38109
> >> +33-4-76188109
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: dev-unsubscribe_at_jersey.dev.java.net
> >> For additional commands, e-mail: dev-help_at_jersey.dev.java.net
> >>
> >>
> >
> >
> >
>
> --
> | ? + ? = To question
> ----------------\
> Paul Sandoz
> x38109
> +33-4-76188109
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: dev-help_at_jersey.dev.java.net
>
>



-- 
Frank D. Martínez M.
Asimov Technologies Ltda.
Blog: http://www.ibstaff.net/fmartinez/