You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@abdera.apache.org by James M Snell <ja...@gmail.com> on 2008/01/26 02:37:05 UTC
TargetBuilder and TemplateTargetBuilder
Up to this point, providers/collectionadapters have had to handle all of
the details in constructing URIs for feeds and entries. The process was
cumbersome and problematic for many reasons. As part of the server
refactoring, today I checked in a new interface called TargetBuilder (I
know the name sucks) whose job it is to construct urls on behalf of the
collection adapter.
Provider implementations provide the TargetBuilder implementation, which
is accessed by the CollectionAdapter via the RequestContext. There is
currently one TargetBuilder implementation, TemplateTargetBuilder, which
uses the URI Template code in the i18n module to construct URLs.
The DefaultProvider and BasicProvider each use their own internal
TargetBuilder implementations. It is possible for developers to
override those implementations but it's not likely that they will.
Custom provider implementations will need to provide their own Target
Builder implementations,
For instance, if you look at
/branches/server_refactor_all/server/src/test/java/org/apache/abdera/protocol/server/test/custom/CustomProvider.java,
you will see:
setTargetBuilder(
new TemplateTargetBuilder()
.setTemplate(TargetType.TYPE_SERVICE, "{target_base}/atom")
.setTemplate(TargetType.TYPE_COLLECTION,
"{target_base}/atom/{collection}{-opt|?|q,c,s,p,l,i,o}{-join|&|q,c,s,p,l,i,o}")
.setTemplate(TargetType.TYPE_CATEGORIES,
"{target_base}/atom/{collection};categories")
.setTemplate(TargetType.TYPE_ENTRY,
"{target_base}/atom/{collection}/{entry}")
.setTemplate(OpenSearchFilter.TYPE_OPENSEARCH_DESCRIPTION,
"{target_base}/search")
);
Then, in
/branches/server_refactor_all/server/src/test/java/org/apache/abdera/protocol/server/test/custom/SimpleAdapter.java,
you will see:
private String getEntryLink(RequestContext request, String entryid) {
Map<String,String> params = new HashMap<String,String>();
params.put("collection",
request.getTarget().getParameter("collection"));
params.put("entry", entryid);
return request.resolveIri(TargetType.TYPE_ENTRY, params);
}
Note that the collection adapter calls the RequestContext, which uses
the target builder to construct the URI.
Because the target builder is using the URI Template implementation, the
input parameter in getEntryLink(..) can be a Map<String,Object>, a
org.apache.abdera.i18n.templates.Context implementation, or any java
bean with public getters. For instance, this would work also:
public class Foo {
public String getCollection() {return "feed";}
}
private String getEntryLink(RequestContext request, String entryid) {
return request.resolveIri(TargetType.TYPE_ENTRY, new Foo());
}
The TemplateTargetBuilder provides a number of built-in variables that
can be used within the URI Templates.
{request_context_path} = the servlet context path of the current request
{request_content_type} = the mime content type of the current request
{request_uri} = the request uri (relative) of the current request
{request_resolved_uri} = the absolute request uri of the current request
{request_language} = the value of the current requests Accept-Language
{request_charset} = the value of the current requests Accept-Charset
{request_user} = the name of the authenticated user
{target_identity} = the value of Target.getIdentity()
{target_path} = the subset of the request uri used to identify the
target
{target_base} = the root of the target_path, usually the contextpath +
the servlet path
{request_parameter_[name]} = the value of
requestContext.getParameter("[name]")
{request_attribute_[name]} = the value of
requestContext.getAttribute(Scope.REQUEST,
"[name]")
{session_attribute_[name]} = the value of
requestContext.getAttribute(Scope.SESSION,
"[name]")
{request_header_[name]} = the value of
requestContext.getHeader("[name]")
{target_parameter_[name]} = the value of Target.getParameter("[name]")
These variables can be used anywhere within any of the URI Templates
defined on TemplateTargetBuilder.
DefaultProvider and BasicProvider both use the TemplateTargetBuilder
internally, but define a number of default templates. To add your own
templates (or to override the defaults), you need to subclass the provider..
public class MyProvider extends DefaultProvider {
public MyProvider() {
TemplateTargetBuilder ttb =
(TemplateTargetBuilder) getTargetBuilder(null);
ttb.setTemplate("foo", "{target_base}/my/custom/template");
}
}
Then, in your CollectionAdapter, you can call...
request.resolveIri("foo", null);
Anyway, the code is checked into the server_refactor_all branch. As
always, comments/feedback are welcomed and requested.
- James
Re: TargetBuilder and TemplateTargetBuilder
Posted by David Primmer <da...@gmail.com>.
I haven't had a chance to look at the details but Vasu and I were just
discussing this and saying that this was a big outstanding need for the
Server. My background is in Python and the class act in that area is
Routes, http://routes.groovie.org/ a powerful package that took
resolving/dispatching and url generation ideas from Ruby on Rails and has
been evolving a lot recently. I don't know a Java package that does this or
is focused in this area but I wanted to suggest it as the best system that I
know of. One of the nicer features is auto-generating rest urls for a given
object:http://routes.groovie.org/manual.html#restful-services
davep
On Jan 25, 2008 5:37 PM, James M Snell <ja...@gmail.com> wrote:
> Up to this point, providers/collectionadapters have had to handle all of
> the details in constructing URIs for feeds and entries. The process was
> cumbersome and problematic for many reasons. As part of the server
> refactoring, today I checked in a new interface called TargetBuilder (I
> know the name sucks) whose job it is to construct urls on behalf of the
> collection adapter.
>
> Provider implementations provide the TargetBuilder implementation, which
> is accessed by the CollectionAdapter via the RequestContext. There is
> currently one TargetBuilder implementation, TemplateTargetBuilder, which
> uses the URI Template code in the i18n module to construct URLs.
>
> The DefaultProvider and BasicProvider each use their own internal
> TargetBuilder implementations. It is possible for developers to
> override those implementations but it's not likely that they will.
>
> Custom provider implementations will need to provide their own Target
> Builder implementations,
>
> For instance, if you look at
>
> /branches/server_refactor_all/server/src/test/java/org/apache/abdera/protocol/server/test/custom/CustomProvider.java,
> you will see:
>
> setTargetBuilder(
> new TemplateTargetBuilder()
> .setTemplate(TargetType.TYPE_SERVICE, "{target_base}/atom")
> .setTemplate(TargetType.TYPE_COLLECTION,
>
> "{target_base}/atom/{collection}{-opt|?|q,c,s,p,l,i,o}{-join|&|q,c,s,p,l,i,o}")
> .setTemplate(TargetType.TYPE_CATEGORIES,
> "{target_base}/atom/{collection};categories")
> .setTemplate(TargetType.TYPE_ENTRY,
> "{target_base}/atom/{collection}/{entry}")
> .setTemplate(OpenSearchFilter.TYPE_OPENSEARCH_DESCRIPTION,
> "{target_base}/search")
> );
>
> Then, in
>
> /branches/server_refactor_all/server/src/test/java/org/apache/abdera/protocol/server/test/custom/SimpleAdapter.java,
> you will see:
>
> private String getEntryLink(RequestContext request, String entryid) {
> Map<String,String> params = new HashMap<String,String>();
> params.put("collection",
> request.getTarget().getParameter("collection"));
> params.put("entry", entryid);
> return request.resolveIri(TargetType.TYPE_ENTRY, params);
> }
>
> Note that the collection adapter calls the RequestContext, which uses
> the target builder to construct the URI.
>
> Because the target builder is using the URI Template implementation, the
> input parameter in getEntryLink(..) can be a Map<String,Object>, a
> org.apache.abdera.i18n.templates.Context implementation, or any java
> bean with public getters. For instance, this would work also:
>
> public class Foo {
> public String getCollection() {return "feed";}
> }
> private String getEntryLink(RequestContext request, String entryid) {
> return request.resolveIri(TargetType.TYPE_ENTRY, new Foo());
> }
>
> The TemplateTargetBuilder provides a number of built-in variables that
> can be used within the URI Templates.
>
> {request_context_path} = the servlet context path of the current request
> {request_content_type} = the mime content type of the current request
> {request_uri} = the request uri (relative) of the current request
> {request_resolved_uri} = the absolute request uri of the current request
> {request_language} = the value of the current requests Accept-Language
> {request_charset} = the value of the current requests Accept-Charset
> {request_user} = the name of the authenticated user
> {target_identity} = the value of Target.getIdentity()
> {target_path} = the subset of the request uri used to identify the
> target
> {target_base} = the root of the target_path, usually the contextpath +
> the servlet path
> {request_parameter_[name]} = the value of
> requestContext.getParameter("[name]")
> {request_attribute_[name]} = the value of
> requestContext.getAttribute(Scope.REQUEST,
> "[name]")
> {session_attribute_[name]} = the value of
> requestContext.getAttribute(Scope.SESSION,
> "[name]")
> {request_header_[name]} = the value of
> requestContext.getHeader("[name]")
> {target_parameter_[name]} = the value of Target.getParameter("[name]")
>
> These variables can be used anywhere within any of the URI Templates
> defined on TemplateTargetBuilder.
>
> DefaultProvider and BasicProvider both use the TemplateTargetBuilder
> internally, but define a number of default templates. To add your own
> templates (or to override the defaults), you need to subclass the
> provider..
>
> public class MyProvider extends DefaultProvider {
> public MyProvider() {
> TemplateTargetBuilder ttb =
> (TemplateTargetBuilder) getTargetBuilder(null);
> ttb.setTemplate("foo", "{target_base}/my/custom/template");
> }
> }
>
> Then, in your CollectionAdapter, you can call...
>
> request.resolveIri("foo", null);
>
> Anyway, the code is checked into the server_refactor_all branch. As
> always, comments/feedback are welcomed and requested.
>
> - James
>
Re: TargetBuilder and TemplateTargetBuilder
Posted by David Primmer <da...@gmail.com>.
I haven't had a chance to look at the details but Vasu and I were just
discussing this and saying that this was a big outstanding need for the
Server. My background is in Python and the class act in that area is
Routes, http://routes.groovie.org/ a powerful package that took
resolving/dispatching and url generation ideas from Ruby on Rails and has
been evolving a lot recently. I don't know a Java package that does this or
is focused in this area but I wanted to suggest it as the best system that I
know of. One of the nicer features is auto-generating rest urls for a given
object:http://routes.groovie.org/manual.html#restful-services
davep
On Jan 25, 2008 5:37 PM, James M Snell <ja...@gmail.com> wrote:
> Up to this point, providers/collectionadapters have had to handle all of
> the details in constructing URIs for feeds and entries. The process was
> cumbersome and problematic for many reasons. As part of the server
> refactoring, today I checked in a new interface called TargetBuilder (I
> know the name sucks) whose job it is to construct urls on behalf of the
> collection adapter.
>
> Provider implementations provide the TargetBuilder implementation, which
> is accessed by the CollectionAdapter via the RequestContext. There is
> currently one TargetBuilder implementation, TemplateTargetBuilder, which
> uses the URI Template code in the i18n module to construct URLs.
>
> The DefaultProvider and BasicProvider each use their own internal
> TargetBuilder implementations. It is possible for developers to
> override those implementations but it's not likely that they will.
>
> Custom provider implementations will need to provide their own Target
> Builder implementations,
>
> For instance, if you look at
>
> /branches/server_refactor_all/server/src/test/java/org/apache/abdera/protocol/server/test/custom/CustomProvider.java,
> you will see:
>
> setTargetBuilder(
> new TemplateTargetBuilder()
> .setTemplate(TargetType.TYPE_SERVICE, "{target_base}/atom")
> .setTemplate(TargetType.TYPE_COLLECTION,
>
> "{target_base}/atom/{collection}{-opt|?|q,c,s,p,l,i,o}{-join|&|q,c,s,p,l,i,o}")
> .setTemplate(TargetType.TYPE_CATEGORIES,
> "{target_base}/atom/{collection};categories")
> .setTemplate(TargetType.TYPE_ENTRY,
> "{target_base}/atom/{collection}/{entry}")
> .setTemplate(OpenSearchFilter.TYPE_OPENSEARCH_DESCRIPTION,
> "{target_base}/search")
> );
>
> Then, in
>
> /branches/server_refactor_all/server/src/test/java/org/apache/abdera/protocol/server/test/custom/SimpleAdapter.java,
> you will see:
>
> private String getEntryLink(RequestContext request, String entryid) {
> Map<String,String> params = new HashMap<String,String>();
> params.put("collection",
> request.getTarget().getParameter("collection"));
> params.put("entry", entryid);
> return request.resolveIri(TargetType.TYPE_ENTRY, params);
> }
>
> Note that the collection adapter calls the RequestContext, which uses
> the target builder to construct the URI.
>
> Because the target builder is using the URI Template implementation, the
> input parameter in getEntryLink(..) can be a Map<String,Object>, a
> org.apache.abdera.i18n.templates.Context implementation, or any java
> bean with public getters. For instance, this would work also:
>
> public class Foo {
> public String getCollection() {return "feed";}
> }
> private String getEntryLink(RequestContext request, String entryid) {
> return request.resolveIri(TargetType.TYPE_ENTRY, new Foo());
> }
>
> The TemplateTargetBuilder provides a number of built-in variables that
> can be used within the URI Templates.
>
> {request_context_path} = the servlet context path of the current request
> {request_content_type} = the mime content type of the current request
> {request_uri} = the request uri (relative) of the current request
> {request_resolved_uri} = the absolute request uri of the current request
> {request_language} = the value of the current requests Accept-Language
> {request_charset} = the value of the current requests Accept-Charset
> {request_user} = the name of the authenticated user
> {target_identity} = the value of Target.getIdentity()
> {target_path} = the subset of the request uri used to identify the
> target
> {target_base} = the root of the target_path, usually the contextpath +
> the servlet path
> {request_parameter_[name]} = the value of
> requestContext.getParameter("[name]")
> {request_attribute_[name]} = the value of
> requestContext.getAttribute(Scope.REQUEST,
> "[name]")
> {session_attribute_[name]} = the value of
> requestContext.getAttribute(Scope.SESSION,
> "[name]")
> {request_header_[name]} = the value of
> requestContext.getHeader("[name]")
> {target_parameter_[name]} = the value of Target.getParameter("[name]")
>
> These variables can be used anywhere within any of the URI Templates
> defined on TemplateTargetBuilder.
>
> DefaultProvider and BasicProvider both use the TemplateTargetBuilder
> internally, but define a number of default templates. To add your own
> templates (or to override the defaults), you need to subclass the
> provider..
>
> public class MyProvider extends DefaultProvider {
> public MyProvider() {
> TemplateTargetBuilder ttb =
> (TemplateTargetBuilder) getTargetBuilder(null);
> ttb.setTemplate("foo", "{target_base}/my/custom/template");
> }
> }
>
> Then, in your CollectionAdapter, you can call...
>
> request.resolveIri("foo", null);
>
> Anyway, the code is checked into the server_refactor_all branch. As
> always, comments/feedback are welcomed and requested.
>
> - James
>