You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2011/12/30 22:45:52 UTC

svn commit: r1225934 - in /abdera/abdera2: core/src/main/java/org/apache/abdera2/model/ core/src/main/java/org/apache/abdera2/parser/axiom/ docs/Getting.Started/ security/src/main/java/org/apache/abdera2/security/

Author: jmsnell
Date: Fri Dec 30 21:45:52 2011
New Revision: 1225934

URL: http://svn.apache.org/viewvc?rev=1225934&view=rev
Log:
documentation, a few api usability enhancements.. including a new setDateExtension() method (and related methods) on the Atom ExtensibleElement interface, intended to make it easier to add simple Date Construct extensions to Atom elements.

Modified:
    abdera/abdera2/core/src/main/java/org/apache/abdera2/model/DateTime.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/model/DateTimeWrapper.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/model/ExtensibleElement.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/model/ExtensibleElementWrapper.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMDateTime.java
    abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMExtensibleElement.java
    abdera/abdera2/docs/Getting.Started/atom.xml
    abdera/abdera2/security/src/main/java/org/apache/abdera2/security/Security.java

Modified: abdera/abdera2/core/src/main/java/org/apache/abdera2/model/DateTime.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/src/main/java/org/apache/abdera2/model/DateTime.java?rev=1225934&r1=1225933&r2=1225934&view=diff
==============================================================================
--- abdera/abdera2/core/src/main/java/org/apache/abdera2/model/DateTime.java (original)
+++ abdera/abdera2/core/src/main/java/org/apache/abdera2/model/DateTime.java Fri Dec 30 21:45:52 2011
@@ -70,6 +70,8 @@ public interface DateTime extends Elemen
      */
     DateTime setValue(org.joda.time.DateTime dateTime);
 
+    DateTime setValueNow();
+    
     /**
      * Sets the content value of the element
      * 

Modified: abdera/abdera2/core/src/main/java/org/apache/abdera2/model/DateTimeWrapper.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/src/main/java/org/apache/abdera2/model/DateTimeWrapper.java?rev=1225934&r1=1225933&r2=1225934&view=diff
==============================================================================
--- abdera/abdera2/core/src/main/java/org/apache/abdera2/model/DateTimeWrapper.java (original)
+++ abdera/abdera2/core/src/main/java/org/apache/abdera2/model/DateTimeWrapper.java Fri Dec 30 21:45:52 2011
@@ -55,6 +55,10 @@ public abstract class DateTimeWrapper ex
             setText("");
         return this;
     }
+    
+    public DateTime setValueNow() {
+      return this.setValue(DateTimes.now());
+    }
 
     public DateTime setDate(Date date) {
         if (date != null)

Modified: abdera/abdera2/core/src/main/java/org/apache/abdera2/model/ExtensibleElement.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/src/main/java/org/apache/abdera2/model/ExtensibleElement.java?rev=1225934&r1=1225933&r2=1225934&view=diff
==============================================================================
--- abdera/abdera2/core/src/main/java/org/apache/abdera2/model/ExtensibleElement.java (original)
+++ abdera/abdera2/core/src/main/java/org/apache/abdera2/model/ExtensibleElement.java Fri Dec 30 21:45:52 2011
@@ -131,6 +131,50 @@ public interface ExtensibleElement exten
     Element addSimpleExtension(String namespace, String localPart, String prefix, String value);
 
     /**
+     * Adds a simple date extension (date content only)
+     * 
+     * @param qname An XML QName
+     * @param value The DateTime value of the element
+     * @return the newly created extension element
+     */
+    Element addDateExtension(QName qname, org.joda.time.DateTime value);
+    
+    /**
+     * Adds a simple extension (text content only)
+     * 
+     * @param namespace An XML namespace
+     * @param localPart A local name
+     * @param prefix A namespace prefix
+     * @param value The DateTime value
+     * @return The newly created extension element
+     */
+    Element addDateExtension(String namespace, String localPart, String prefix, org.joda.time.DateTime value);   
+    
+    /**
+     * Adds a simple date extension (date content only)
+     * 
+     * @param qname An XML QName
+     * @param value The DateTime value of the element
+     * @return the newly created extension element
+     */
+    Element addDateExtensionNow(QName qname);
+    
+    /**
+     * Adds a simple extension (text content only)
+     * 
+     * @param namespace An XML namespace
+     * @param localPart A local name
+     * @param prefix A namespace prefix
+     * @param value The DateTime value
+     * @return The newly created extension element
+     */
+    Element addDateExtensionNow(String namespace, String localPart, String prefix);  
+    
+    org.joda.time.DateTime getDateExtension(QName qname);
+    
+    org.joda.time.DateTime getDateExtension(String namespace, String localpart, String prefix);
+    
+    /**
      * Gets the value of a simple extension
      * 
      * @param qname An XML QName

Modified: abdera/abdera2/core/src/main/java/org/apache/abdera2/model/ExtensibleElementWrapper.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/src/main/java/org/apache/abdera2/model/ExtensibleElementWrapper.java?rev=1225934&r1=1225933&r2=1225934&view=diff
==============================================================================
--- abdera/abdera2/core/src/main/java/org/apache/abdera2/model/ExtensibleElementWrapper.java (original)
+++ abdera/abdera2/core/src/main/java/org/apache/abdera2/model/ExtensibleElementWrapper.java Fri Dec 30 21:45:52 2011
@@ -23,6 +23,7 @@ import javax.xml.namespace.QName;
 
 import org.apache.abdera2.common.selector.Selector;
 import org.apache.abdera2.factory.Factory;
+import org.joda.time.DateTime;
 
 /**
  * ElementWrapper implementation that implements the ExtensibleElement interface. This should be used to create static
@@ -134,6 +135,44 @@ public abstract class ExtensibleElementW
     public <T extends Element> T addExtension(Class<T> _class, QName before) {
       return getExtInternal().addExtension(_class,before);
     }
+
+    public Element addDateExtension(QName qname, DateTime value) {
+      return getExtInternal().addDateExtension(qname, value);
+    }
+
+    public Element addDateExtension(
+      String namespace, 
+      String localPart,
+      String prefix, 
+      DateTime value) {
+        return getExtInternal().addDateExtension(
+          namespace,localPart,prefix, value);
+    }
+
+    public Element addDateExtensionNow(QName qname) {
+      return getExtInternal().addDateExtensionNow(qname);
+    }
+
+    public Element addDateExtensionNow(
+      String namespace, 
+      String localPart,
+      String prefix) {
+        return getExtInternal().addDateExtensionNow(
+          namespace, localPart, prefix);
+    }
+
+    public DateTime getDateExtension(QName qname) {
+      return getExtInternal().getDateExtension(qname);
+    }
+
+    public DateTime getDateExtension(
+      String namespace, 
+      String localpart,
+      String prefix) {
+        return getExtInternal().getDateExtension(
+          namespace, localpart, prefix);
+    }
+    
     
     
 }

Modified: abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMDateTime.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMDateTime.java?rev=1225934&r1=1225933&r2=1225934&view=diff
==============================================================================
--- abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMDateTime.java (original)
+++ abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMDateTime.java Fri Dec 30 21:45:52 2011
@@ -88,6 +88,10 @@ public class FOMDateTime extends FOMElem
         return value;
     }
 
+    public DateTime setValueNow() {
+      return setValue(DateTimes.now());
+    }
+    
     public DateTime setValue(org.joda.time.DateTime dateTime) {
         complete();
         value = null;

Modified: abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMExtensibleElement.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMExtensibleElement.java?rev=1225934&r1=1225933&r2=1225934&view=diff
==============================================================================
--- abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMExtensibleElement.java (original)
+++ abdera/abdera2/core/src/main/java/org/apache/abdera2/parser/axiom/FOMExtensibleElement.java Fri Dec 30 21:45:52 2011
@@ -22,6 +22,7 @@ import java.util.List;
 import javax.xml.namespace.QName;
 
 import org.apache.abdera2.common.anno.AnnoUtil;
+import org.apache.abdera2.common.date.DateTimes;
 import org.apache.abdera2.common.selector.Selector;
 import org.apache.abdera2.model.Element;
 import org.apache.abdera2.model.ElementIteratorWrapper;
@@ -35,6 +36,7 @@ import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.OMXMLParserWrapper;
+import org.joda.time.DateTime;
 
 @SuppressWarnings({"unchecked","rawtypes"})
 public class FOMExtensibleElement extends FOMElement implements ExtensibleElement {
@@ -229,4 +231,60 @@ public class FOMExtensibleElement extend
         throw new IllegalArgumentException();
       return (T)addExtension(qname,before);
     }
+
+    public Element addDateExtension(QName qname, DateTime value) {
+      complete();
+      FOMFactory fomfactory = (FOMFactory)factory;
+      org.apache.abdera2.model.DateTime el = 
+        fomfactory.newDateTime(qname, this);
+      el.setValue(value);
+      String prefix = qname.getPrefix();
+      declareIfNecessary(qname.getNamespaceURI(), prefix);
+      return el;
+    }
+
+    public Element addDateExtension(
+      String namespace, 
+      String localPart,
+      String prefix, 
+      DateTime value) {
+        complete();
+        declareIfNecessary(namespace, prefix);
+        return addDateExtension(
+          prefix != null ? 
+            new QName(namespace, localPart, prefix) : 
+            new QName(namespace, localPart),
+          value);
+    }
+
+    public Element addDateExtensionNow(QName qname) {
+      return addDateExtension(qname, DateTimes.now());
+    }
+
+    public Element addDateExtensionNow(
+      String namespace, 
+      String localPart,
+      String prefix) {
+        return addDateExtension(
+          namespace,
+          localPart,
+          prefix,
+          DateTimes.now());
+    }
+
+    public DateTime getDateExtension(QName qname) {
+      Element el = getExtension(qname);
+      if (el instanceof org.apache.abdera2.model.DateTime) {
+        org.apache.abdera2.model.DateTime dt = 
+          (org.apache.abdera2.model.DateTime) el;
+        return dt.getValue();
+      } else return null;
+    }
+
+    public DateTime getDateExtension(
+      String namespace, 
+      String localpart,
+      String prefix) {
+        return getDateExtension(new QName(namespace,localpart,prefix));
+    }
 }

Modified: abdera/abdera2/docs/Getting.Started/atom.xml
URL: http://svn.apache.org/viewvc/abdera/abdera2/docs/Getting.Started/atom.xml?rev=1225934&r1=1225933&r2=1225934&view=diff
==============================================================================
--- abdera/abdera2/docs/Getting.Started/atom.xml (original)
+++ abdera/abdera2/docs/Getting.Started/atom.xml Fri Dec 30 21:45:52 2011
@@ -547,7 +547,7 @@ foo.MyListExtensionFactory
    
   </section>
   
-  <section title="Atom Date Constructs">
+  <section title="Date Constructs">
   
    <t>The Atom format requires that all dates and times be formatted to match 
    the date-time construct from RFC 3339. The basic format is 
@@ -568,6 +568,280 @@ foo.MyListExtensionFactory
   // you can use the shortcut setUpdatedNow() method
   entry.setUpdatedNow();
    </artwork></figure>
+   
+   <t>The Joda-Time DateTime class provides a host of additional benefits and 
+   features relative to the old Abdera 1.x AtomDate class, including Date
+   Arithmetic operations.</t>
+   
+   <figure><preamble>For instance, to indicate that an entry was updated 
+   five minutes prior to the current date and time, you can use the following:</preamble>
+   <artwork>
+  entry.setUpdated(DateTimes.now().minusMinutes(5));
+   </artwork></figure>
+  
+   <t>The DateTime class has also been integrated with the Abdera2 Selector 
+   Framework and Guava Libraries Predicate API to enable powerful filtering 
+   options.</t>
+   
+   <figure><preamble>For instance, if you have an Atom feed and want to retrieve
+   a listing of only the Entry objects whose updated timestamps fall within a 
+   given range, you can call:</preamble><artwork><![CDATA[
+  import static org.apache.abdera2.model.selector.Selectors.updated;
+  import static org.apache.abdera2.common.date.DateTimes.between;
+   
+  Feed feed = ...
+  DateTime date1 = ...
+  DateTime date2 = ...
+    
+  feed.getEntries(
+    updated(
+      between(
+        date1,date2)));
+    
+   ]]></artwork></figure>
+  
+   <section title="Date Construct Extensions">
+   
+   <t>The Atom format explicitly allows the Atom Date Construct to be reused 
+   by extensions. This means you can create your own extension elements that 
+   use the same syntax rules as the atom:updated, atom:published and 
+   app:edited elements. Such extensions can use the dynamic and static 
+   extension APIs:</t>
+   
+   <figure><preamble>Adding a Date Construct Extension using the dynamic API:</preamble>
+   <artwork><![CDATA[
+  Entry entry = ...
+  QName qname = new QName("foo");  
+  entry.addDateExtension(qname, DateTimes.now());
+   ]]></artwork></figure>
+   
+   <t>Note that the addDateExtension on the Abdera Entry class is new in Abdera2.</t>
+   
+   <figure><preamble>More complex extensions of the Date Construct can be implemented
+   statically by extending the DateTimeWrapper abstract class:</preamble>
+   <artwork><![CDATA[
+  import javax.xml.namespace.QName;
+
+  import org.apache.abdera2.factory.Factory;
+  import org.apache.abdera2.model.DateTimeWrapper;
+  import org.apache.abdera2.model.Element;
+
+  public class MyDateElement 
+    extends DateTimeWrapper {
+
+    public MyDateElement(Element internal) {
+      super(internal);
+    }
+
+    public MyDateElement(Factory factory, QName qname) {
+      super(factory, qname);
+    }
+  
+    ...
+  }
+   ]]></artwork></figure>
+   
+   </section>
+  
+  </section>
+  
+  <section title="Person Constructs">
+  
+    <t>Atom defines the notion of a Person Construct to represent people 
+    and entities. A Person Construct consists minimally of a name, an 
+    optional email address and an optional URI.</t>
+    
+    <figure><artwork><![CDATA[
+  Person person = entry.addAuthor(
+    "John Doe", 
+    "john.doe@example.org", 
+    "http://example.org/~jdoe");
+
+  System.out.println(person.getName());
+  System.out.println(person.getEmail());
+  System.out.println(person.getUri());
+    ]]></artwork></figure>
+  
+    <section title="Person Construct Extensions">
+    
+    <t>The Atom format explicitly allows the Atom Person Construct to be 
+    reused by extensions. This means you can create your own extension elements 
+    that use the same syntax rules as the atom:author and atom:contributor 
+    elements. Such extensions can use the dynamic and static extension APIs:</t>
+    
+    <figure><artwork><![CDATA[
+  Entry entry = ...
+  QName qname = new QName("urn:foo","foo","x");
+  Person person = abdera.getFactory().newPerson(qname, entry);
+  person.setName("John Doe");
+  person.setEmail("john.doe@example.org");
+  person.setUri("http://example.org/~jdoe");
+    ]]></artwork></figure>
+    
+    <figure><preamble>The resulting extension element:</preamble>
+    <artwork><![CDATA[
+  <x:foo xmlns:x="urn:foo">
+    <name>John Doe</name>
+    <email>john.doe@example.org</email>
+    <uri>http://example.org/~jdoe</uri>
+  </x:foo>
+    ]]></artwork></figure>
+  
+      <t>Static Person Construct extensions can be implemented by extending
+      the org.apache.abdera2.model.PersonWrapper abstract class.</t>
+    
+    </section>
+  
+  </section>
+  
+  <section title="Atom Links">
+  
+  <t>Atom link elements are similar in design to the link tag used in HTML 
+  and XHTML. They can be added to feed, entry and source objects.</t>
+  
+  <figure><preamble>Adding a link to an Atom Entry:</preamble>
+  <artwork><![CDATA[
+  entry.addLink(
+    "http://example.org/foo",  // href
+    Link.REL_ALTERNATE,        // rel
+    "text/html",               // type
+    "Link Title",              // title
+    "en-US",                   // hreflang
+    12345);                    // length
+  ]]></artwork></figure>
+  
+  <t>The rel attribute specifies the meaning of the link. The value of rel can 
+  either be a simple name or an IRI. Simple names MUST be registered with 
+  <eref="http://www.iana.org/assignments/link-relations/link-relations.xml">IANA</eref>. 
+  Note that each of the values in the IANA registry have a full IRI 
+  equivalent value, e.g., the value "http://www.iana.org/assignments/relation/alternate" 
+  is equivalent to the simple name "alternate". Any rel attribute value that 
+  is not registered MUST be an IRI.</t>
+  
+  <figure><artwork><![CDATA[
+  entry.addLink(
+    "http://example.org/foo",  // href
+    "http://example.com/custom/link/rel"); // rel
+  ]]></artwork></figure>
+  
+  </section>
+  
+  <section title="Signatures and Encryption">
+  
+  <t>Abdera supports digital signatures and encryption of Atom documents.</t>
+  
+  <section title="Signing an Atom Document">
+  
+    <figure><preamble>Initialize the Signing Key:</preamble>
+    <artwork><![CDATA[
+  KeyStore ks = KeyStore.getInstance(keystoreType);
+  InputStream in = DSig.class.getResourceAsStream(keystoreFile);    
+  ks.load(in, keystorePass.toCharArray());
+  PrivateKey signingKey = 
+    (PrivateKey) ks.getKey(
+      privateKeyAlias,
+      privateKeyPass.toCharArray());
+  X509Certificate cert = 
+    (X509Certificate) ks.getCertificate(
+      certificateAlias);
+    ]]></artwork></figure>
+    
+    <figure><preamble>Prepare the entry to sign:</preamble>
+    <artwork><![CDATA[
+  Entry entry = abdera.newEntry();
+      
+  entry.setId("http://example.org/foo/entry");  
+  entry.setUpdatedNow();
+  entry.setTitle("This is an entry");
+  entry.setContentAsXhtml("This <b>is</b> <i>markup</i>");
+  entry.addAuthor("James");
+  entry.addLink("http://www.example.org");
+    ]]></artwork></figure>
+    
+    <figure><preamble>Prepare the signing options:</preamble>
+    <artwork><![CDATA[
+  Security absec = new Security(abdera);
+  SignatureOptions options = 
+    absec.getSignature()
+      .getDefaultSignatureOptions();    
+  options.setCertificate(cert);
+  options.setSigningKey(signingKey); 
+    ]]></artwork></figure>
+    
+    <figure><preamble>Sign the entry:</preamble>
+    <artwork><![CDATA[
+  entry = (Entry)security.signer(options).apply(entry);
+    ]]></artwork></figure>
+  
+    <figure><preamble>Verifying the signed entry:</preamble>
+    <artwork><![CDATA[
+  boolean verified = security.verifier().apply(entry);
+  System.out.println(verified);
+    ]]></artwork></figure>
+
+    <t>Note that the signer() and verifier() methods on the 
+    org.apache.abdera2.security.Security class are new within Abdera2 and 
+    return Guava Function objects that wrap the signing and verification
+    logic.</t>
+  
+  </section>
+  
+  <section title="Encrypting an Atom Document">
+  
+   <t>Any valid Java crypto provider can be used. In these examples, we are 
+   using the <eref target="http://www.bouncycastle.org/">Bouncy Castle</eref> provider.</t>
+   
+   <figure><preamble>Prepare the provider and the encryption key:</preamble>
+   <artwork><![CDATA[
+  KeyHelper.prepareDefaultJceProvider();
+  
+  String jceAlgorithmName = "AES";
+  KeyGenerator keyGenerator =
+      KeyGenerator.getInstance(jceAlgorithmName);
+  keyGenerator.init(128);
+  SecretKey key = keyGenerator.generateKey();
+   ]]></artwork></figure>
+   
+   <figure><preamble>Prepare the entry to encrypt:</preamble>
+   <artwork><![CDATA[
+  Entry entry = abdera.newEntry();
+  entry.setId("http://example.org/foo/entry");
+  entry.setUpdatedNow();
+  entry.setTitle("This is an entry");
+  entry.setContentAsXhtml("This <b>is</b> <i>markup</i>");
+  entry.addAuthor("James");
+  entry.addLink("http://www.example.org");
+   ]]></artwork></figure>
+   
+   <figure><preamble>Prepare the encryption options:</preamble>
+   <artwork><![CDATA[
+  Security absec = new Security(abdera);
+  EncryptionOptions options =
+   absec.getEncryption()
+     .getDefaultEncryptionOptions();
+  options.setDataEncryptionKey(key);
+   ]]></artwork></figure>
+   
+   <figure><preamble>Encrypt the document:</preamble>
+   <artwork<![CDATA[
+  Document<Element> enc = 
+    absec.encryptor(options)
+      .apply(entry.getDocument());
+   ]]></figure>
+  
+   <figure><preamble>Decrypting the document:</preamble>
+   <artwork><![CDATA[
+  Document<Element> ent = 
+    absec.decryptor(options)
+      .apply(enc);
+   ]]></artwork></figure>
+   
+   <t>Note that the encryptor() and decryptor() methods on the 
+   org.apache.abdera2.security.Security class are new in Abdera2
+   are return Guava Function objects that wrap the encryption and
+   decryption logic.</t>
+  
+  </section>
   
   </section>
   

Modified: abdera/abdera2/security/src/main/java/org/apache/abdera2/security/Security.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/security/src/main/java/org/apache/abdera2/security/Security.java?rev=1225934&r1=1225933&r2=1225934&view=diff
==============================================================================
--- abdera/abdera2/security/src/main/java/org/apache/abdera2/security/Security.java (original)
+++ abdera/abdera2/security/src/main/java/org/apache/abdera2/security/Security.java Fri Dec 30 21:45:52 2011
@@ -113,6 +113,10 @@ public class Security {
       };
     }
     
+    public <T extends Element>Function<T,Boolean> verifier() {
+      return verifier(null);
+    }
+    
     public <T extends Element>Function<T,Boolean> verifier(final SignatureOptions options) {
       return new Function<T,Boolean>() {
         public Boolean apply(T input) {