Author: jmsnell
Date: Wed Mar 14 21:25:45 2007
New Revision: 518473
URL: http://svn.apache.org/viewvc?view=rev&rev=518473
Log:
Adding the server document contributed by Adam Constabaris (https://issues.apache.org/jira/browse/ABDERA-38)
Thanks Adam!
Added:
incubator/abdera/java/trunk/docs/serverimpl.html
Modified:
incubator/abdera/java/trunk/docs/building.html
incubator/abdera/java/trunk/docs/gettingstarted.html
incubator/abdera/java/trunk/docs/index.html
Modified: incubator/abdera/java/trunk/docs/building.html
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/docs/building.html?view=diff&rev=518473&r1=518472&r2=518473
==============================================================================
--- incubator/abdera/java/trunk/docs/building.html (original)
+++ incubator/abdera/java/trunk/docs/building.html Wed Mar 14 21:25:45 2007
@@ -25,7 +25,7 @@
<!-- Header -->
<div id="banner">
<h1><a href="http://incubator.apache.org/abdera">Apache Abdera</a></h1>
- <p>Version 0.2.2 (Incubating)</p>
+ <p>Version 0.3.0-SNAPSHOT (Incubating)</p>
<hr/>
</div>
<div id="divider"></div>
Modified: incubator/abdera/java/trunk/docs/gettingstarted.html
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/docs/gettingstarted.html?view=diff&rev=518473&r1=518472&r2=518473
==============================================================================
--- incubator/abdera/java/trunk/docs/gettingstarted.html (original)
+++ incubator/abdera/java/trunk/docs/gettingstarted.html Wed Mar 14 21:25:45 2007
@@ -24,7 +24,7 @@
<!-- Header -->
<div id="banner">
<h1><a href="http://incubator.apache.org/abdera">Apache Abdera</a></h1>
- <p>Version 0.2.2 (Incubating)</p>
+ <p>Version 0.3.0-SNAPSHOT (Incubating)</p>
<hr/>
</div>
<div id="divider"></div>
Modified: incubator/abdera/java/trunk/docs/index.html
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/docs/index.html?view=diff&rev=518473&r1=518472&r2=518473
==============================================================================
--- incubator/abdera/java/trunk/docs/index.html (original)
+++ incubator/abdera/java/trunk/docs/index.html Wed Mar 14 21:25:45 2007
@@ -28,7 +28,7 @@
<body>
<div id="banner">
<h1><a href="http://incubator.apache.org/abdera">Apache Abdera</a></h1>
- <p>Version 0.2.2 (Incubating)</p>
+ <p>Version 0.3.0-SNAPSHOT (Incubating)</p>
<hr/>
</div>
<div id="divider"></div>
@@ -37,6 +37,7 @@
<ul>
<li><a href="building.html">Building</a></li>
<li><a href="gettingstarted.html">Getting Started</a></li>
+ <li><a href="serverimpl.html">Implementing a Server</a></li>
<li><a href="api/index.html">Javadocs</a></li>
</ul>
</div>
Added: incubator/abdera/java/trunk/docs/serverimpl.html
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/docs/serverimpl.html?view=auto&rev=518473
==============================================================================
--- incubator/abdera/java/trunk/docs/serverimpl.html (added)
+++ incubator/abdera/java/trunk/docs/serverimpl.html Wed Mar 14 21:25:45 2007
@@ -0,0 +1,158 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. The ASF licenses this file to You
+ under the Apache License, Version 2.0 (the "License"); you may not
+ use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. For additional information regarding
+ copyright in this work, please see the NOTICE file in the top level
+ directory of this distribution. -->
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Apache Abdera</title>
+ <meta name="generator" content="DocBook XSL Stylesheets V1.70.1"/>
+ </head>
+ <body>
+ <!-- Header -->
+ <div id="banner">
+ <h1><a href="http://incubator.apache.org/abdera">Apache Abdera</a></h1>
+ <p>Version 0.3.0-SNAPSHOT (Incubating)</p>
+ <hr/>
+ </div>
+ <div id="divider"></div>
+
+ <h1>Implementing A Server</h1>
+
+ <div class="article" lang="en">
+ <div class="titlepage">
+ <div><div class="author">
+ <h3 class="author">Contributed by: <span class="firstname">Adam</span>
<span class="surname">Constabaris</span></h3>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="toc"><p><b>Table of Contents</b></p><dl><dt><span
class="section"><a href="#intro">Introduction</a></span></dt><dt><span
class="section"><a href="#providers">Implementing <code class="classname">Provider</code></a></span></dt><dt><span
class="section"><a href="#app_assembly">Putting it all together</a></span></dt></dl></div><div
class="section" lang="en"><div class="titlepage"><div><div><h2 class="title"
style="clear: both"><a id="intro"/>Introduction</h2></div></div></div><p>The
framework for implementing an APP server in Abdera is, as shipped, incomplete, but
+ armed with a knowledge of how APP works, you shouldn't have too much trouble
enabling
+ APP access to an (appropriate!) domain model. In order to effectively use the
classes in
+ the framework, you'll have to know how to configure them and what you need to
implement
+ yourself. The first part of the document describes (loosely) how Abdera is configured,
+ while the second part concerns notes about implementing some of the more important
+ classes. I assume throughout that you are familiar with the Atom format, APP
basics, and
+ Abdera's general model for representing the Atom format. </p><p>
Abdera is designed to use a controller servlet, and ships with a basic implementation
+ that is be suitable for a range of situations. Changing your Abdera server configuration
+ is largely achieved by setting properties of the form
+ <code class="literal">some.abdera.framework.Interface=my.domain.abdera.InterfaceImplementation</code>;
+ that is, the property's name is the fully qualified name of the interface whose
+ implementation you want to specify, and the value is the fully-qualified name
of a class
+ that implements that interface. Swapping out Abdera's default parser factory
for a
+ SAX-based one, for example, would be done by setting
+ <span class="property">org.apache.abdera.parser.ParserFactory</span>
to (say)
+ <span class="property">net.my.domain.MyParserFactory</span>.
</p><p> Properties can be specified in a number of places; first, most of the
crucial bits of
+ core Abdera are specified in <code class="classname">org.apache.abdera.util.Constants</code>.
+ You can also use the Java standard <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider"
target="_top">service provider</a> mechanism, or a file named
+ <code class="filename">abdera.properties</code> on the classpath
(generally, values are looked up
+ in this order, with later values overriding ones set by earlier mechanisms).
While
+ Abdera core ships with settings that allow you to parse or create feed documents
without
+ any special configuration, server implementations are more variable and so require
more
+ work. </p><p>As you might expect, this form of configuration makes
heavy use of reflection, and
+ default or well-known constructors. In general, if you don't need to supply a
lot of
+ helper classes or are happy using (e.g) JNDI lookup mechanisms to look up such
things as
+ database connections, you can use these mechanisms without too much fuss. It's
also not
+ much more work to use a dependency injection framework (such as Spring) for your
server
+ configuration. </p><p> The interfaces you need to implement in order
to create an APP server are listed in
+ <code class="classname">org.apache.abdera.protocol.server.util.ServerConstants</code>:
</p><div class="variablelist"><dl><dt><span class="term">
+
+ <code class="classname">org.apache.abdera.protocol.server.servlet.RequestHandlerManager</code>
+ </span></dt><dd><p>Factory for objects that control
the request processing.</p></dd><dt><span class="term">
+ <code class="classname">org.apache.abdera.protocol.server.auth.SubjectResolver</code>
+ </span></dt><dd><p>Factory for objects that determine
the identity of calling
+ clients.</p></dd><dt><span class="term">
+ <code class="classname">org.apache.abdera.protocol.server.provider.TargetResolver</code>
+ </span></dt><dd><p>Factory for objects that determine
the type of APP entity involved
+ in the request (e.g. entry, collection, media, service, categories)</p></dd><dt><span
class="term">
+
+ <code class="classname">org.apache.abdera.protocol.server.ServiceContext</code>
+ </span></dt><dd><p>Controller: coordinates all
of the other factory classes.</p></dd><dt><span class="term">
+ <code class="classname">org.apache.abdera.protocol.server.provider.ProviderManager</code>
+ </span></dt><dd><p>Factory for <code class="classname">Provider</code>
implementations that
+ implement the CRUD operations of the APP server.</p></dd></dl></div><p>
+ </p><p> The <code class="classname">org.apache.abdera.protocol.server.provider.Provider</code>
+
+ interface defines all of the CRUD operations involved in the Atom protocol: this
is
+ where you put the code that gets entries, collections, service documents,and
handles
+ updates and deletions; most of the rest of these classes are involved in making
sure an
+ HTTP request is routed to the right method on the <code class="classname">Provider</code>.
Since
+ the <code class="classname">ProviderManager</code> class is responsible
for instantiating and
+ configuring your <code class="classname">Provider</code> objects,
it has an important role to
+ play. Concrete default implementations for most of the other interfaces are provided,
+ but you will have to provide implementations for both
+ <code class="classname">ProviderManager</code> and <code class="classname">Provider</code>.
</p><p> An absolutely minimal APP server will also have to configure a target
resolver, i.e. provide
+ a way to determine which kind of APP entity is being operated on (i.e. it answers
questions of
+ the form "is this a request for a service document?"). In all likelihood, a
subclass of
+ <code class="classname">org.apache.abdera.protocol.server.util.RegexTargetResolver</code>
+
+ will suffice here, since it maps request URIs that match a particular regular
expression
+ to entity types. Your subclass can supply the actual mapping that you're going
to use
+ (see <code class="classname">SimpleTargetResolver</code> in the server
example). Additionally, since the
+ <code class="classname">ServiceContext</code> is responsible for getting
references to all these other
+ classes and configuring them (most importantly the <code class="classname">ProviderManager</code>),
you'll
+ probably want to subclass it as well.
+ </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2
class="title" style="clear: both"><a id="providers"/>Implementing <code class="classname">Provider</code></h2></div></div></div><p>While
the specifics are going to be largely determined by the type of information your
+ server is processing and how it's stored (e.g. on a file system vs. rows in a
database),
+ there are a few things to look out for that apply to any <code class="classname">Provider</code>
+ implementation. One thing you'll definitely need is need a system for turning
objects in
+ your domain model into Abdera's model objects, and vice-versa. This part has
to be left
+ as an exercise for the reader. </p><p>Most of the methods in the
<span class="interface">Provider</span> interface are fairly well
+ described by their names: <code class="methodname">getEntry</code>,
for example, is called when
+ the client has called <code class="literal">GET</code> on an entry
URI. One exception here is the
+ <code class="methodname">getInfo</code> method, which serves
mainly to enable support for
+ HTTP's <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3"
target="_top">conditional GET</a> [ <a href="http://fishbowl.pastiche.org/2002/10/21/http_conditional_get_for_rss_hackers"
target="_top">see also</a> ]. </p><p> You'll notice that the various
<code class="methodname">getXXX</code> methods return a
+ <code class="classname">ResponseInfo</code> object, which encompasses
the HTTP response,
+ including the headers and response body. In addition to the
+ <code class="classname">RequestContext</code> argument, these methods
also accept a
+ <code class="literal">boolean</code> argument that determines
whether the method is evaluating
+ the request for cacheability<sup>[<a id="d0e180" href="#ftn.d0e180">1</a>]</sup>
or whether it should actually generate a response body. Let's refer to the
+ first mode (where the boolean parameter is <code class="literal">false</code>)
as "header mode"
+ and the second as "full response mode". When the method is called in header mode,
it
+ <span class="emphasis"><em>may</em></span> check
the <code class="literal">ETag</code> or
+ <code class="literal">If-Modified-Since</code> HTTP headers submitted
by the APP client
+ against the entry's current tag or modification time. </p><p>So,
if you're implementing conditional GET in your <code class="classname">Provider</code>,
+ the <code class="methodname">getInfo</code> method can delegate to
the appropriate
+ <code class="methodname">getXXX</code> method in header mode.
Even if your provider
+ <span class="emphasis"><em>doesn't</em></span> support
conditional GET, you'll probably want to
+ support different header and full response modes, to avoid having to generate
a
+ potentially "expensive" document twice. A relatively straightforward way to do
this is
+ to have your methods return an <code class="classname">EmptyResponseContext</code>
with a status
+ code of 200 (or 404, if the user's requested an entry that doesn't exist) when
they're
+ called in header mode. The default request processing pipeline ensures that the
method
+ will be called again in full response mode.</p></div><div class="section"
lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear:
both"><a id="app_assembly"/>Putting it all together</h2></div></div></div><p>The
default <code class="classname">AbderaServlet</code> class can be used as your
servlet controller, but
+ it is somewhat limited in how much "help" it can provide by way of making servlet
or EJB container resources such as
+ database connection pools available to your protocol implementation. <code
class="classname">AbderaServlet</code>
+
+ uses the property-resolution mechanisms described above<sup>[<a id="d0e224"
href="#ftn.d0e224">2</a>]</sup>. The basic
+ steps it uses to process a request are:
+ </p><div class="procedure"><ol type="1"><li><p>Obtain
a reference to a <code class="classname">ServiceContext</code> (via reflection).</p></li><li><p>Use
the service context to get a reference to a <code class="classname">RequestHandlerManager</code>.</p></li><li><p>Use
the request handler manager to obtain a <code class="classname">RequestHandler</code>.</p></li><li><p>Call
<code class="methodname">process()</code> on the request handler.</p></li></ol></div><p>
+
+ If your <code class="classname">ServiceContext</code> implementation
can get references to
+ appropriately configured target resolvers and provider managers, then all you
need to do
+ is map the AbderaServlet to the desired URI and set the <span class="property">org.apache.abdera.protocol.server.ServiceContext</span>
+ property to the name of your service context implementation.
+ </p><p>
+ If you require greater control over how the <code class="classname">ServiceContext</code>
is instantiated or
+ configured, you should create your own servlet whose <code class="methodname">service</code>
method executes
+ this basic process.
+ </p></div><div class="footnotes"><br/><hr width="100"
align="left"/><div class="footnote"><p><sup>[<a id="ftn.d0e180" href="#d0e180">1</a>]
</sup>They can also check that certain preconditions are satisfied,
+ e.g. the "lost update" mechanism for a PUT (update) request, which checks
+ whether the ETag supplied by the client matches the current ETag for
the
+ associated entry, but I'll leave that part out.</p></div><div
class="footnote"><p><sup>[<a id="ftn.d0e224" href="#d0e224">2</a>]
</sup>With one twist: it also lets you specify your
+ implementation classes via the servlet's initialization parameters.</p></div></div></div></body></html>
\ No newline at end of file
|