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) {