You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by aj...@apache.org on 2009/04/06 13:55:51 UTC

svn commit: r762294 - in /incubator/jspwiki/trunk: src/java/org/apache/wiki/api/ src/java/org/apache/wiki/workflow/ tests/java/org/apache/wiki/workflow/

Author: ajaquith
Date: Mon Apr  6 11:55:50 2009
New Revision: 762294

URL: http://svn.apache.org/viewvc?rev=762294&view=rev
Log:
[JSPWIKI-304] Changed all Workflow signatures so that all attribute values are now Serializable. This has required some minor changes to WikiContext get/setAttribute, such that these must also be Serializable too. In practice this is not a problem, because all attributes passed to WikiContext were always Strings anyway. The net effect of this change is that we can now make workflows persistent across engine restarts! (Coming later...)

Modified:
    incubator/jspwiki/trunk/src/java/org/apache/wiki/api/WikiPage.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/AbstractStep.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Decision.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/DecisionQueue.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Step.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Workflow.java
    incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/WorkflowManager.java
    incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/ApprovalWorkflowTest.java
    incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/DecisionQueueTest.java
    incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/SimpleDecisionTest.java
    incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/TaskTest.java
    incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/WorkflowManagerTest.java
    incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/WorkflowTest.java

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/api/WikiPage.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/api/WikiPage.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/api/WikiPage.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/api/WikiPage.java Mon Apr  6 11:55:50 2009
@@ -21,6 +21,7 @@
 package org.apache.wiki.api;
 
 import java.io.InputStream;
+import java.io.Serializable;
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
@@ -78,7 +79,7 @@
      *  @param key The key to use for fetching the attribute
      *  @return The attribute.  If the attribute has not been set, returns null.
      */
-    public Object getAttribute( String key );
+    public Serializable getAttribute( String key );
 
     /**
      *  Sets an metadata attribute.
@@ -87,7 +88,7 @@
      *  @param key The key for the attribute used to fetch the attribute later on.
      *  @param attribute The attribute value
      */
-    public void setAttribute( String key, Object attribute );
+    public void setAttribute( String key, Serializable attribute );
 
     /**
      * Returns the full attributes Map, in case external code needs
@@ -97,7 +98,7 @@
      * @return The attribute Map.  Please note that this is a direct
      *         reference, not a copy.
      */
-    public Map getAttributes();
+    public Map<String,Serializable> getAttributes();
 
     /**
      *  Removes an attribute from the page, if it exists.
@@ -106,7 +107,7 @@
      *  @return If the attribute existed, returns the object.
      *  @since 2.1.111
      */
-    public Object removeAttribute( String key );
+    public Serializable removeAttribute( String key );
 
     /**
      *  Returns the date when this page was last modified.

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/AbstractStep.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/AbstractStep.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/AbstractStep.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/AbstractStep.java Mon Apr  6 11:55:50 2009
@@ -112,7 +112,7 @@
     /**
      * {@inheritDoc}
      */
-    public final Collection getAvailableOutcomes()
+    public final Collection<Outcome> getAvailableOutcomes()
     {
         Set<Outcome> outcomes = m_successors.keySet();
         return Collections.unmodifiableCollection( outcomes );
@@ -121,7 +121,7 @@
     /**
      * {@inheritDoc}
      */
-    public final List getErrors()
+    public final List<String> getErrors()
     {
         return Collections.unmodifiableList( m_errors );
     }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Decision.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Decision.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Decision.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Decision.java Mon Apr  6 11:55:50 2009
@@ -189,7 +189,7 @@
      * 
      * @return the list of Facts
      */
-    public final List getFacts()
+    public final List<Fact> getFacts()
     {
         return Collections.unmodifiableList( m_facts );
     }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/DecisionQueue.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/DecisionQueue.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/DecisionQueue.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/DecisionQueue.java Mon Apr  6 11:55:50 2009
@@ -99,7 +99,7 @@
      *            the wiki session
      * @return the collection of Decisions, which may be empty
      */
-    public Collection getActorDecisions(WikiSession session)
+    public Collection<Decision> getActorDecisions(WikiSession session)
     {
         ArrayList<Decision> decisions = new ArrayList<Decision>();
         if ( session.isAuthenticated() )

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Step.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Step.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Step.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Step.java Mon Apr  6 11:55:50 2009
@@ -89,7 +89,7 @@
      * 
      * @return the set of outcomes
      */
-    public Collection getAvailableOutcomes();
+    public Collection<Outcome> getAvailableOutcomes();
 
     /**
      * Returns a List of error strings generated by this Step. If this Step
@@ -97,7 +97,7 @@
      * 
      * @return the errors
      */
-    public List getErrors();
+    public List<String> getErrors();
 
     /**
      * <p>

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Workflow.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Workflow.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Workflow.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/Workflow.java Mon Apr  6 11:55:50 2009
@@ -229,7 +229,7 @@
     public static final int CREATED = -2;
 
     /** Lazily-initialized attribute map. */
-    private Map<String, Object> m_attributes;
+    private Map<String, Serializable> m_attributes;
 
     /** The initial Step for this Workflow. */
     private Step m_firstStep;
@@ -377,14 +377,14 @@
     }
 
     /**
-     * Retrieves a named Object associated with this Workflow. If the Workflow
+     * Retrieves a named object associated with this Workflow. If the Workflow
      * has completed or aborted, this method always returns <code>null</code>.
      *
      * @param attr
      *            the name of the attribute
      * @return the value
      */
-    public final synchronized Object getAttribute( String attr )
+    public final synchronized Serializable getAttribute( String attr )
     {
         if ( m_attributes == null )
         {
@@ -508,7 +508,7 @@
      * @return an array of Steps representing those that have executed, or are
      *         currently executing
      */
-    public final List getHistory()
+    public final List<Step> getHistory()
     {
         return Collections.unmodifiableList( m_history );
     }
@@ -603,11 +603,11 @@
      * @param obj
      *            the value
      */
-    public final synchronized void setAttribute(String attr, Object obj )
+    public final synchronized void setAttribute(String attr, Serializable obj )
     {
         if ( m_attributes == null )
         {
-            m_attributes = new HashMap<String, Object>();
+            m_attributes = new HashMap<String, Serializable>();
         }
         m_attributes.put( attr, obj );
     }

Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/WorkflowManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/WorkflowManager.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/WorkflowManager.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/workflow/WorkflowManager.java Mon Apr  6 11:55:50 2009
@@ -88,7 +88,7 @@
      *
      * @return the current workflows
      */
-    public Collection getWorkflows()
+    public Collection<Workflow> getWorkflows()
     {
         return new HashSet<Workflow>( m_workflows );
     }
@@ -97,7 +97,7 @@
      * Returns a collection of finished workflows; that is, those that have aborted or completed.
      * @return the finished workflows
      */
-    public List getCompletedWorkflows()
+    public List<Workflow> getCompletedWorkflows()
     {
         return new ArrayList<Workflow>( m_completed );
     }
@@ -198,11 +198,11 @@
     }
 
     /**
-     * Protected helper method that returns the associated WikiEngine
+     * Returns the associated WikiEngine
      *
      * @return the wiki engine
      */
-    protected WikiEngine getEngine()
+    public WikiEngine getEngine()
     {
         if ( m_engine == null )
         {
@@ -244,7 +244,7 @@
      * @param session the wiki session
      * @return the collection workflows the wiki session owns, which may be empty
      */
-    public Collection getOwnerWorkflows( WikiSession session )
+    public Collection<Workflow> getOwnerWorkflows( WikiSession session )
     {
         List<Workflow> workflows = new ArrayList<Workflow>();
         if ( session.isAuthenticated() )

Modified: incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/ApprovalWorkflowTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/ApprovalWorkflowTest.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/ApprovalWorkflowTest.java (original)
+++ incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/ApprovalWorkflowTest.java Mon Apr  6 11:55:50 2009
@@ -27,15 +27,14 @@
 
 import junit.framework.TestCase;
 
-import org.apache.wiki.PageManager;
 import org.apache.wiki.TestEngine;
 import org.apache.wiki.WikiContext;
 import org.apache.wiki.api.FilterException;
 import org.apache.wiki.api.WikiException;
 import org.apache.wiki.auth.Users;
 import org.apache.wiki.auth.WikiPrincipal;
+import org.apache.wiki.content.ContentManager;
 import org.apache.wiki.filters.BasicPageFilter;
-import org.apache.wiki.workflow.*;
 
 
 public class ApprovalWorkflowTest extends TestCase
@@ -113,7 +112,7 @@
         assertNotNull( w.getAttribute( "task.preSaveWikiPage") );
         assertEquals( new WikiPrincipal( Users.JANNE ), decision.getActor() );
         assertEquals( decisionKey, decision.getMessageKey() );
-        List decisionFacts = ((Decision)decision).getFacts();
+        List<Fact> decisionFacts = ((Decision)decision).getFacts();
         assertEquals( 3, decisionFacts.size() );
         assertEquals( facts[0], decisionFacts.get(0) );
         assertEquals( facts[1], decisionFacts.get(1) );
@@ -204,11 +203,11 @@
         assertFalse( m_engine.pageExists(pageName));
 
         // Second, GroupPrincipal Admin should see a Decision in its queue
-        Collection decisions = m_dq.getActorDecisions( m_engine.adminSession() );
+        Collection<Decision> decisions = m_dq.getActorDecisions( m_engine.adminSession() );
         assertEquals(1, decisions.size());
 
         // Now, approve the decision and it should go away, and page should appear.
-        Decision decision = (Decision)decisions.iterator().next();
+        Decision decision = decisions.iterator().next();
         decision.decide(Outcome.DECISION_APPROVE);
         assertTrue( m_engine.pageExists(pageName));
         decisions = m_dq.getActorDecisions( m_engine.adminSession() );
@@ -236,19 +235,19 @@
         assertFalse( m_engine.pageExists(pageName));
 
         // ...and there should be a Decision in GroupPrincipal Admin's queue
-        Collection decisions = m_dq.getActorDecisions( m_engine.adminSession() );
+        Collection<Decision> decisions = m_dq.getActorDecisions( m_engine.adminSession() );
         assertEquals(1, decisions.size());
 
         // Now, DENY the decision and the page should still not exist...
-        Decision decision = (Decision)decisions.iterator().next();
+        Decision decision = decisions.iterator().next();
         decision.decide(Outcome.DECISION_DENY);
         assertFalse( m_engine.pageExists(pageName) );
 
         // ...but there should also be a notification decision in Janne's queue
         decisions = m_dq.getActorDecisions( m_engine.janneSession() );
         assertEquals(1, decisions.size());
-        decision = (Decision)decisions.iterator().next();
-        assertEquals(PageManager.SAVE_REJECT_MESSAGE_KEY, decision.getMessageKey());
+        decision = decisions.iterator().next();
+        assertEquals(ContentManager.SAVE_REJECT_MESSAGE_KEY, decision.getMessageKey());
 
         // Once Janne disposes of the notification, his queue should be empty
         decision.decide(Outcome.DECISION_ACKNOWLEDGE);

Modified: incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/DecisionQueueTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/DecisionQueueTest.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/DecisionQueueTest.java (original)
+++ incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/DecisionQueueTest.java Mon Apr  6 11:55:50 2009
@@ -29,7 +29,6 @@
 import org.apache.wiki.api.WikiException;
 import org.apache.wiki.auth.GroupPrincipal;
 import org.apache.wiki.auth.WikiPrincipal;
-import org.apache.wiki.workflow.*;
 
 import junit.framework.TestCase;
 
@@ -152,7 +151,7 @@
 
     public void testActorDecisions()
     {
-        Collection decisions = m_queue.getActorDecisions(adminSession);
+        Collection<Decision> decisions = m_queue.getActorDecisions(adminSession);
         assertEquals(1, decisions.size());
 
         decisions = m_queue.getActorDecisions(janneSession);
@@ -183,9 +182,9 @@
         assertEquals(decision, w.getCurrentStep());
 
         // Verify that it's also in Janne's DecisionQueue
-        Collection decisions = m_queue.getActorDecisions(janneSession);
+        Collection<Decision> decisions = m_queue.getActorDecisions(janneSession);
         assertEquals(1, decisions.size());
-        Decision d = (Decision)decisions.iterator().next();
+        Decision d = decisions.iterator().next();
         assertEquals(decision, d);
 
         // Make Decision, and verify that it's gone from the queue

Modified: incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/SimpleDecisionTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/SimpleDecisionTest.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/SimpleDecisionTest.java (original)
+++ incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/SimpleDecisionTest.java Mon Apr  6 11:55:50 2009
@@ -25,7 +25,6 @@
 
 import org.apache.wiki.api.WikiException;
 import org.apache.wiki.auth.WikiPrincipal;
-import org.apache.wiki.workflow.*;
 
 import junit.framework.TestCase;
 
@@ -53,7 +52,7 @@
         m_decision.addFact(f3);
 
         // The facts should be available, and returned in order
-        List facts = m_decision.getFacts();
+        List<Fact> facts = m_decision.getFacts();
         assertEquals(f1, facts.get(0));
         assertEquals(f2, facts.get(1));
         assertEquals(f3, facts.get(2));
@@ -104,7 +103,7 @@
         m_decision.addError("Error deciding something.");
         m_decision.addError("Error deciding something else.");
 
-        List errors = m_decision.getErrors();
+        List<String> errors = m_decision.getErrors();
         assertEquals(2, errors.size());
         assertEquals("Error deciding something.", errors.get(0));
         assertEquals("Error deciding something else.", errors.get(1));
@@ -112,7 +111,7 @@
 
     public void testAvailableOutcomes()
     {
-        Collection outcomes = m_decision.getAvailableOutcomes();
+        Collection<Outcome> outcomes = m_decision.getAvailableOutcomes();
         assertTrue(outcomes.contains(Outcome.DECISION_APPROVE));
         assertTrue(outcomes.contains(Outcome.DECISION_DENY));
         assertFalse(outcomes.contains(Outcome.DECISION_HOLD));

Modified: incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/TaskTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/TaskTest.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/TaskTest.java (original)
+++ incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/TaskTest.java Mon Apr  6 11:55:50 2009
@@ -25,7 +25,6 @@
 
 import org.apache.wiki.api.WikiException;
 import org.apache.wiki.auth.WikiPrincipal;
-import org.apache.wiki.workflow.*;
 
 import junit.framework.TestCase;
 
@@ -109,7 +108,7 @@
         m_task.addError("Error deciding something.");
         m_task.addError("Error deciding something else.");
 
-        List errors = m_task.getErrors();
+        List<String> errors = m_task.getErrors();
         assertEquals(2, errors.size());
         assertEquals("Error deciding something.", errors.get(0));
         assertEquals("Error deciding something else.", errors.get(1));
@@ -117,7 +116,7 @@
 
     public void testAvailableOutcomes()
     {
-        Collection outcomes = m_task.getAvailableOutcomes();
+        Collection<Outcome> outcomes = m_task.getAvailableOutcomes();
         assertFalse(outcomes.contains(Outcome.DECISION_APPROVE));
         assertFalse(outcomes.contains(Outcome.DECISION_DENY));
         assertFalse(outcomes.contains(Outcome.DECISION_HOLD));

Modified: incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/WorkflowManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/WorkflowManagerTest.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/WorkflowManagerTest.java (original)
+++ incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/WorkflowManagerTest.java Mon Apr  6 11:55:50 2009
@@ -27,7 +27,6 @@
 import org.apache.wiki.api.WikiException;
 import org.apache.wiki.auth.GroupPrincipal;
 import org.apache.wiki.auth.WikiPrincipal;
-import org.apache.wiki.workflow.*;
 
 import junit.framework.TestCase;
 
@@ -86,7 +85,7 @@
         wm.start(w);
         assertEquals(1, wm.getWorkflows().size());
         assertEquals(0, wm.getCompletedWorkflows().size());
-        Workflow workflow = (Workflow)wm.getWorkflows().iterator().next();
+        Workflow workflow = wm.getWorkflows().iterator().next();
         assertEquals(w, workflow);
         assertEquals(1, workflow.getId());
         

Modified: incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/WorkflowTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/WorkflowTest.java?rev=762294&r1=762293&r2=762294&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/WorkflowTest.java (original)
+++ incubator/jspwiki/trunk/tests/java/org/apache/wiki/workflow/WorkflowTest.java Mon Apr  6 11:55:50 2009
@@ -27,7 +27,6 @@
 import org.apache.wiki.api.WikiException;
 import org.apache.wiki.auth.GroupPrincipal;
 import org.apache.wiki.auth.WikiPrincipal;
-import org.apache.wiki.workflow.*;
 
 import junit.framework.TestCase;
 



Re: svn commit: r762294 - in /incubator/jspwiki/trunk: src/java/org/apache/wiki/api/ src/java/org/apache/wiki/workflow/ tests/java/org/apache/wiki/workflow/

Posted by Andrew Jaquith <an...@gmail.com>.
Yup. Whatever works is fine with me. My intent with this particular
set of changes was to get Workflows prepped for persistence. If and
when you make method/signature changes on WikiPage, the refactoring
will be easy.

On Mon, Apr 6, 2009 at 10:09 AM, Janne Jalkanen <ja...@iki.fi> wrote:
> From WikiPage
>
>> -    public Object getAttribute( String key );
>> +    public Serializable getAttribute( String key );
>
> I'm sort of leaning towards getting rid of these generic methods and having something like
>
> Date getDateAttribute(String key)
> Long getLongAttribute(String key)
> String getAttribute(String key)
>
> And vice versa
>
> void setAttribute(String key, Date value)
>
> This allows us to make some basic automatic translations (e.g you can
> still get a Long attribute as a String, it'll just be the result of
> Long.toString()) but most of all, it gets rid of annoying casting
> needs and ClassCastExceptions.
>
>> -    public Map getAttributes();
>> +    public Map<String,Serializable> getAttributes();
>
> This I am hoping to get rid of soon.  With the very large attributes
> we will be seeing, this is just not a feasible API.
>
> /Janne
>

Re: svn commit: r762294 - in /incubator/jspwiki/trunk: src/java/org/apache/wiki/api/ src/java/org/apache/wiki/workflow/ tests/java/org/apache/wiki/workflow/

Posted by Janne Jalkanen <ja...@iki.fi>.
>From WikiPage

> -    public Object getAttribute( String key );
> +    public Serializable getAttribute( String key );

I'm sort of leaning towards getting rid of these generic methods and having something like

Date getDateAttribute(String key)
Long getLongAttribute(String key)
String getAttribute(String key)

And vice versa

void setAttribute(String key, Date value)

This allows us to make some basic automatic translations (e.g you can
still get a Long attribute as a String, it'll just be the result of
Long.toString()) but most of all, it gets rid of annoying casting
needs and ClassCastExceptions.

> -    public Map getAttributes();
> +    public Map<String,Serializable> getAttributes();

This I am hoping to get rid of soon.  With the very large attributes
we will be seeing, this is just not a feasible API.

/Janne