abdera-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmsn...@apache.org
Subject svn commit: r518473 - in /incubator/abdera/java/trunk/docs: building.html gettingstarted.html index.html serverimpl.html
Date Thu, 15 Mar 2007 04:25:47 GMT
Author: jmsnell
Date: Wed Mar 14 21:25:45 2007
New Revision: 518473

URL: http://svn.apache.org/viewvc?view=rev&rev=518473
Adding the server document contributed by Adam Constabaris (https://issues.apache.org/jira/browse/ABDERA-38)

Thanks Adam!


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>
   <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>
   <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 @@
   <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>
   <div id="divider"></div>
@@ -37,6 +37,7 @@
       <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>

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,
+  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
+            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
+            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).
+            Abdera core ships with settings that allow you to parse or create feed documents
+            any special configuration, server implementations are more variable and so require
+            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
+            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
+                        <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
+            where you put the code that gets entries, collections, service documents,and
+            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>.
+            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
+            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>),
+            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
+            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,
+                <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
+            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
+            called in header mode. The default request processing pipeline ensures that the
+            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
+            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
+                    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

View raw message