Author: ross.gardler
Date: Fri Sep 12 16:44:33 2008
New Revision: 1306

Added:
     
trunk/uk.ac.osswatch.simal.rest/src/documentation/content/xdocs/developer/implementNewCommand.xml
Modified:
    trunk/uk.ac.osswatch.simal.rest/src/documentation/content/xdocs/site.xml

Log:
Document how to implement a new REST command

Added:  
trunk/uk.ac.osswatch.simal.rest/src/documentation/content/xdocs/developer/implementNewCommand.xml
==============================================================================
--- (empty file)
+++  
trunk/uk.ac.osswatch.simal.rest/src/documentation/content/xdocs/developer/implementNewCommand.xml
        
Fri Sep 12 16:44:33 2008
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2007 University of Oxford
+
+  Licensed 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.
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation  
V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd";>
+<document>
+  <header>
+    <title>Implementing a new REST command</title>
+  </header>
+  <body>
+    <p>This document is designed to guide you in the implementation
+    of a new REST command in Simal. To illustrate the process
+    we will document the creation of the command to get all
+    people from the repository.</p>
+
+    <section>
+      <title>Test First Development</title>
+      <p>Simal does not accept new features without test code.
+      Therefore it makes sense to follow the test first development
+      model. In this model the first thing we do is create a test
+      that fails.</p>
+
+      <p>Since this command is about people it will be implemented
+      in the ParsonAPI class, therefore our test should go into the
+      TestPersonAPI class. Our first test code will be:</p>
+
+      <source>
+package uk.ac.osswatch.simal.rest;
+
+...
+
+public class TestPersonAPI extends AbstractAPITest {
+
+...
+
+  @Test
+  public void testGetAllPeopleAsJSON() throws SimalAPIException {
+    RESTCommand command = RESTCommand.createCommand(RESTCommand.ALL_PEOPLE
+        + RESTCommand.FORMAT_JSON);
+    IAPIHandler handler = SimalHandlerFactory.createHandler(command,  
getRepo());
+    String result = handler.execute();
+    assertNotNull("No JSON Returned by getAllPeoplen", result);
+  }
+}
+      </source>
+
+      <p>This code will not compile until we add  
<code>RESTCommand.ALL_PEOPLE</code>.
+      So lets do that now:</p>
+
+      <source>
+package uk.ac.osswatch.simal.rest;
+
+...
+
+public final class RESTCommand {
+
+...
+
+  public static final String ALL_PEOPLE = "/allPeople";
+
+...
+
+}
+      </source>
+
+      <p>We've now added a new command that will be recognised in
+      a REST URI, therefore we need to add this to the documentation
+      as follows:</p>
+
+      <source>
+<![CDATA[
+<section>
+  <title>Retrieve all People</title>
+
+  <p>To retrieve the details of all people use:</p>
+
+  <source>http://foo.com/simal-rest/allPeople/FORMAT</source>
+</section>
+]]>
+      </source>
+
+      <p>Now our tests will compile and we can check that
+      it fails as expected when run. I love test driven
+      development, even a failure is a success!</p>
+    </section>
+
+    <section>
+      <title>Making something return</title>
+
+      <p>The next stage is to make something return so that the above
+      test passes. To do this you need to make sure the Simal REST
+      module knows how to handle requests using your new command.
+      Since this is a command provided by the PersonAPI you need
+      to make sure that a call to  
<code>RESTCommand.isPersonCommand()</code>
+      will return true.</p>
+
+      <p>Examining this method shows that we will need an
+      <code>RESTCommand.isGetAllPeople()</code> method. So add
+      the following code to the <code>RESTCommand</code> class:</p>
+
+      <source>
+/**
+ * Test to see if this command is a getAllPEople command.
+ *
+ * @return
+ */
+public boolean isGetAllPeople() {
+  if (params.get(PARAM_METHOD).equals(ALL_PEOPLE)) {
+    return true;
+  }
+  return false;
+}
+      </source>
+
+      <p>Now add this test to the tests made in the
+      <code>isPersonCommand</code> method.</p>
+
+      <p>Now, for sanities sake, we'll run our test again. Of course,
+      it still fails, but now the reason for failure has changed.
+      We've made a difference and the new error "Unknown Command"
+      gives us a clue as to what to do next - implement the command.</p>
+
+      <p>This error is thrown in the <code>PersonAPI.execute()</code>
+      method. A quick glance at that method makes it clear what we need
+      to do. Add the following method to the <code>PersonAPI</code> class  
and
+      call it, when appropriate, from the <code>execute()</code>  
method.</p>
+
+      <source>
+/**
+ * Get all the people in the repository.
+ * @param cmd
+ * @return
+ * @throws SimalAPIException
+ */
+public String getAllPeople(final RESTCommand cmd)
+throws SimalAPIException {
+  return "It's working";
+}
+      </source>
+
+      <p>Clearly this isn't going to actually get the people from
+      the repository, but should be enough to pass our test, which
+      is the objective right now. Run the test to satisfy yourself
+      everything is going well.</p>
+
+    </section>
+
+    <section>
+      <title>Implement the method</title>
+
+      <p>Now we'll actually get the people from the repository.
+      Starting with the JSON format since that is what the test
+      requests.</p>
+
+      <p>First of all, we need a test to tell us when it's
+      working. Add the following code to the test you wrote
+      earlier.</p>
+
+      <source>
+    assertTrue("JSON does not include person name: JSON = " + result,  
result
+        .contains("\"label\":\"Joe Blogs Maintainer\""));
+      </source>
+
+      <p>Run your test and... HURRAH!!!! it fails!</p>
+
+      <p>Now to make it pass. Replace the skeleton code in your
+      <code>getAllPeople()</code> method with:</p>
+
+      <source>
+<![CDATA[
+  /**
+   * Get all the people in the repository.
+   * @param cmd
+   * @return
+   * @throws SimalAPIException
+   */
+  public String getAllPeople(final RESTCommand cmd)
+    throws SimalAPIException {
+    final String id = cmd.getPersonID();
+
+    StringBuffer response = new StringBuffer();
+    try {
+      Iterator<IPerson> itr = getRepository().getAllPeople().iterator();
+      if (cmd.isJSON()) {
+        while(itr.hasNext()) {
+          response.append("{ \"items\": [");
+          response.append(itr.next().toJSON(true));
+          response.append("]}");
+        }
+      } else {
+        throw new SimalAPIException("Unknown data format: " +  
cmd.getFormat());
+      }
+    } catch (SimalRepositoryException e) {
+      throw new SimalAPIException("Unable to get a person with id " + id,  
e);
+    }
+    return response.toString();
+  }
+]]>
+      </source>
+
+      <p>Run your test and... HURRAH!!!! it passes!</p>
+    </section>
+
+    <section>
+      <title>Finishing off</title>
+
+      <p>You should really implement more tests now and you should
+      also implement the other data formats available via the REST
+      API. However, I'm sure you get the idea by now.</p>
+    </section>
+
+
+  </body>
+</document>
\ No newline at end of file

Modified:  
trunk/uk.ac.osswatch.simal.rest/src/documentation/content/xdocs/site.xml
==============================================================================
---  
trunk/uk.ac.osswatch.simal.rest/src/documentation/content/xdocs/site.xml        
 
(original)
+++  
trunk/uk.ac.osswatch.simal.rest/src/documentation/content/xdocs/site.xml        
 
Fri Sep 12 16:44:33 2008
@@ -47,6 +47,7 @@
    <devDocs label="Developer Documentation" tab="restModule">
      <faq label="FAQ" href="developer/faq.html" description="Frequently  
asked questions from developers"/>
      <addProject label="Add Project"  
href="docs/developer/useCases/addProject.html" description="Adding a  
project to the repository"/>
+    <implementNewCmd label="New Command"  
href="developer/implementNewCommand.html" description="How to implement a  
new command"/>
    </devDocs>

    <external-refs>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Simal Commits" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/simal-commits?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to