Return-Path: Delivered-To: apmail-incubator-abdera-dev-archive@locus.apache.org Received: (qmail 38358 invoked from network); 26 Jan 2008 02:11:17 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 26 Jan 2008 02:11:17 -0000 Received: (qmail 26558 invoked by uid 500); 26 Jan 2008 02:11:08 -0000 Delivered-To: apmail-incubator-abdera-dev-archive@incubator.apache.org Received: (qmail 26531 invoked by uid 500); 26 Jan 2008 02:11:08 -0000 Mailing-List: contact abdera-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: abdera-dev@incubator.apache.org Delivered-To: mailing list abdera-dev@incubator.apache.org Received: (qmail 26522 invoked by uid 99); 26 Jan 2008 02:11:07 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 25 Jan 2008 18:11:07 -0800 X-ASF-Spam-Status: No, hits=2.0 required=10.0 tests=HTML_MESSAGE,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of david.primmer@gmail.com designates 209.85.146.181 as permitted sender) Received: from [209.85.146.181] (HELO wa-out-1112.google.com) (209.85.146.181) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 26 Jan 2008 02:10:52 +0000 Received: by wa-out-1112.google.com with SMTP id n4so4465010wag.6 for ; Fri, 25 Jan 2008 18:10:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:references; bh=hGMzUNghcfSCb8gymqRmYfeAHbUy9qb4bvPoJGwHdYk=; b=hNtKbnaqkEIy7ovIRDSd6bI+fzpFVy+1kwEBZa0UNqiVZdzyNbIKRBonIY1AdQ6/qzXzrqDEbAjq+S6cLlvjwc8nomIrulI6Mu0LpKi+03omR0NxLabZWvizKb8EfPlvz9mu+Ww2Ls+2Wj9WTpqNkkyD2kuFKzqaYNXq1VVVkw8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:references; b=YVrMrL42eY/Irtswc0CJZ1cJ0t3xDB3meJ4sz/ryQsFkKpBoA8JwzooVOob/vYuXlbjCgv22AIr1zfpFYWeqst83/dXxi55NqG6kVr6UtA6g7gyXphqzqIDo6pUN+o6QDriqGF19ai1khPYzHe2ZLYioHfv4eOoaFBmlDblmrVs= Received: by 10.114.76.1 with SMTP id y1mr3144173waa.38.1201313444440; Fri, 25 Jan 2008 18:10:44 -0800 (PST) Received: by 10.114.125.15 with HTTP; Fri, 25 Jan 2008 18:10:44 -0800 (PST) Message-ID: Date: Fri, 25 Jan 2008 18:10:44 -0800 From: "David Primmer" To: abdera-dev@incubator.apache.org Subject: Re: TargetBuilder and TemplateTargetBuilder Cc: abdera-user@incubator.apache.org In-Reply-To: <479A8EC1.9070803@gmail.com> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_2174_12163154.1201313444411" References: <479A8EC1.9070803@gmail.com> X-Virus-Checked: Checked by ClamAV on apache.org ------=_Part_2174_12163154.1201313444411 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline 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 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 params = new HashMap(); > 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, 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 > ------=_Part_2174_12163154.1201313444411--