← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 5449: wip, messageconversationcontroller

 

------------------------------------------------------------
revno: 5449
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2011-12-16 10:48:40 +0100
message:
  wip, messageconversationcontroller
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/MessageConversationXmlAdapter.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversations.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/MessageConversationController.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/Message.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversation.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversationStore.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/UserMessage.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/MessageConversationXmlAdapter.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/MessageConversationXmlAdapter.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/MessageConversationXmlAdapter.java	2011-12-16 09:48:40 +0000
@@ -0,0 +1,60 @@
+package org.hisp.dhis.common.adapter;
+
+/*
+ * Copyright (c) 2004-2011, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import org.hisp.dhis.common.BaseIdentifiableObject;
+import org.hisp.dhis.message.MessageConversation;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import java.util.UUID;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class MessageConversationXmlAdapter extends XmlAdapter<BaseIdentifiableObject, MessageConversation>
+{
+    private BaseIdentifiableObjectXmlAdapter baseIdentifiableObjectXmlAdapter = new BaseIdentifiableObjectXmlAdapter();
+
+    @Override
+    public MessageConversation unmarshal( BaseIdentifiableObject identifiableObject ) throws Exception
+    {
+        MessageConversation messageConversation = new MessageConversation();
+
+        messageConversation.setUid( identifiableObject.getUid() );
+        messageConversation.setLastUpdated( identifiableObject.getLastUpdated() );
+        messageConversation.setName( identifiableObject.getName() == null ? UUID.randomUUID().toString() : identifiableObject.getName() );
+
+        return messageConversation;
+    }
+
+    @Override
+    public BaseIdentifiableObject marshal( MessageConversation messageConversation ) throws Exception
+    {
+        return baseIdentifiableObjectXmlAdapter.marshal( messageConversation );
+    }
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/Message.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/Message.java	2011-12-14 09:51:02 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/Message.java	2011-12-16 09:48:40 +0000
@@ -1,7 +1,7 @@
 package org.hisp.dhis.message;
 
 /*
- * Copyright (c) 2004-2010, University of Oslo
+ * Copyright (c) 2004-2011, University of Oslo
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,15 +27,23 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.util.Date;
-
+import org.codehaus.jackson.annotate.JsonProperty;
 import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.common.CodeGenerator;
+import org.hisp.dhis.common.Dxf2Namespace;
 import org.hisp.dhis.user.User;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Date;
+
 /**
  * @author Lars Helge Overland
  */
+@XmlRootElement( name = "message", namespace = Dxf2Namespace.NAMESPACE )
+@XmlAccessorType( value = XmlAccessType.NONE )
 public class Message
     extends BaseIdentifiableObject
 {
@@ -43,7 +51,7 @@
      * The message text.
      */
     private String text;
-    
+
     /**
      * The message meta data, like user agent and OS of sender.
      */
@@ -53,13 +61,13 @@
      * The message sender.
      */
     private User sender;
-    
+
     public Message()
     {
         this.uid = CodeGenerator.generateCode();
         this.lastUpdated = new Date();
     }
-    
+
     public Message( String text, String metaData, User sender )
     {
         this.uid = CodeGenerator.generateCode();
@@ -68,13 +76,15 @@
         this.metaData = metaData;
         this.sender = sender;
     }
-    
+
     @Override
     public String getName()
     {
         return text;
     }
-    
+
+    @XmlElement
+    @JsonProperty
     public String getText()
     {
         return text;
@@ -85,6 +95,8 @@
         this.text = text;
     }
 
+    @XmlElement
+    @JsonProperty
     public String getMetaData()
     {
         return metaData;
@@ -95,6 +107,8 @@
         this.metaData = metaData;
     }
 
+    @XmlElement
+    @JsonProperty
     public User getSender()
     {
         return sender;
@@ -118,22 +132,22 @@
         {
             return true;
         }
-        
+
         if ( object == null )
         {
             return false;
         }
-        
+
         if ( getClass() != object.getClass() )
         {
             return false;
         }
-        
+
         final Message other = (Message) object;
-        
+
         return uid.equals( other.uid );
     }
-    
+
     @Override
     public String toString()
     {

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversation.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversation.java	2011-12-13 16:29:31 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversation.java	2011-12-16 09:48:40 +0000
@@ -27,62 +27,65 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
+import org.codehaus.jackson.annotate.JsonProperty;
 import org.hisp.dhis.common.BaseIdentifiableObject;
+import org.hisp.dhis.common.Dxf2Namespace;
 import org.hisp.dhis.user.User;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.*;
+
 /**
  * @author Lars Helge Overland
  */
+@XmlRootElement( name = "messageConversation", namespace = Dxf2Namespace.NAMESPACE )
+@XmlAccessorType( value = XmlAccessType.NONE )
 public class MessageConversation
     extends BaseIdentifiableObject
 {
     private String subject;
 
     private Set<UserMessage> userMessages = new HashSet<UserMessage>();
-    
+
     private List<Message> messages = new ArrayList<Message>();
 
     private User lastSender;
-    
+
     private transient boolean read;
-    
+
     private transient String lastSenderSurname;
-    
+
     private transient String lastSenderFirstname;
-    
+
     public MessageConversation()
     {
     }
-    
+
     public MessageConversation( String subject, User lastSender )
     {
         this.subject = subject;
         this.lastSender = lastSender;
     }
-    
+
     @Override
     public String getName()
     {
         return subject;
     }
-        
+
     public void addUserMessage( UserMessage userMessage )
     {
         this.userMessages.add( userMessage );
     }
-    
+
     public void addMessage( Message message )
     {
         this.messages.add( message );
     }
-    
+
     public void markRead( User user )
     {
         for ( UserMessage userMessage : userMessages )
@@ -90,7 +93,7 @@
             if ( userMessage.getUser() != null && userMessage.getUser().equals( user ) )
             {
                 userMessage.setRead( true );
-                
+
                 return;
             }
         }
@@ -103,14 +106,14 @@
             if ( userMessage.getUser() != null && userMessage.getUser().equals( user ) )
             {
                 userMessage.setRead( false );
-                
+
                 return;
             }
         }
     }
-    
+
     public void markReplied( User sender, Message message )
-    {   
+    {
         for ( UserMessage userMessage : userMessages )
         {
             if ( userMessage.getUser() != null && !userMessage.getUser().equals( sender ) )
@@ -118,57 +121,51 @@
                 userMessage.setRead( false );
             }
         }
-        
+
         addMessage( message );
-        
+
         this.setLastUpdated( new Date() );
         this.lastSender = sender;
     }
-    
+
     public void remove( User user )
     {
         Iterator<UserMessage> iterator = userMessages.iterator();
-        
+
         while ( iterator.hasNext() )
         {
             UserMessage userMessage = iterator.next();
-            
+
             if ( userMessage.getUser() != null && userMessage.getUser().equals( user ) )
             {
                 iterator.remove();
-                
+
                 return;
             }
         }
     }
-    
+
     public Set<User> getUsers()
     {
         Set<User> users = new HashSet<User>();
-        
+
         for ( UserMessage userMessage : userMessages )
         {
             users.add( userMessage.getUser() );
         }
-        
+
         return users;
     }
-    
+
+    @XmlElement
+    @JsonProperty
     public String getLastSenderName()
     {
         return lastSenderFirstname + " " + lastSenderSurname;
     }
-        
-    public int getId()
-    {
-        return id;
-    }
-
-    public void setId( int id )
-    {
-        this.id = id;
-    }
-
+
+    @XmlElement
+    @JsonProperty
     public String getSubject()
     {
         return subject;
@@ -199,6 +196,8 @@
         this.messages = messages;
     }
 
+    @XmlElement
+    @JsonProperty
     public User getLastSender()
     {
         return lastSender;
@@ -209,6 +208,8 @@
         this.lastSender = lastSender;
     }
 
+    @XmlElement
+    @JsonProperty
     public boolean isRead()
     {
         return read;
@@ -219,6 +220,8 @@
         this.read = read;
     }
 
+    @XmlElement
+    @JsonProperty
     public String getLastSenderSurname()
     {
         return lastSenderSurname;
@@ -229,6 +232,8 @@
         this.lastSenderSurname = lastSenderSurname;
     }
 
+    @XmlElement
+    @JsonProperty
     public String getLastSenderFirstname()
     {
         return lastSenderFirstname;
@@ -252,22 +257,22 @@
         {
             return true;
         }
-        
+
         if ( object == null )
         {
             return false;
         }
-        
+
         if ( getClass() != object.getClass() )
         {
             return false;
         }
-        
+
         final MessageConversation other = (MessageConversation) object;
-        
+
         return uid.equals( other.uid );
     }
-    
+
     @Override
     public String toString()
     {

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversationStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversationStore.java	2011-08-04 07:52:24 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversationStore.java	2011-12-16 09:48:40 +0000
@@ -27,18 +27,18 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import org.hisp.dhis.common.GenericIdentifiableObjectStore;
+import org.hisp.dhis.user.User;
+
 import java.util.List;
 
-import org.hisp.dhis.common.GenericStore;
-import org.hisp.dhis.user.User;
-
 /**
  * @author Lars Helge Overland
  */
 public interface MessageConversationStore
-    extends GenericStore<MessageConversation>
+    extends GenericIdentifiableObjectStore<MessageConversation>
 {
     List<MessageConversation> getMessageConversations( User user, int first, int max );
-    
+
     long getUnreadUserMessageConversationCount( User user );
 }

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversations.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversations.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageConversations.java	2011-12-16 09:48:40 +0000
@@ -0,0 +1,66 @@
+package org.hisp.dhis.message;
+
+/*
+ * Copyright (c) 2004-2011, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.hisp.dhis.common.BaseIdentifiableObject;
+import org.hisp.dhis.common.Dxf2Namespace;
+import org.hisp.dhis.common.adapter.MessageConversationXmlAdapter;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+@XmlRootElement( name = "messages", namespace = Dxf2Namespace.NAMESPACE )
+@XmlAccessorType( value = XmlAccessType.NONE )
+public class MessageConversations
+{
+    private List<MessageConversation> messageConversations = new ArrayList<MessageConversation>();
+
+    @XmlElement( name = "message" )
+    @XmlJavaTypeAdapter( MessageConversationXmlAdapter.class )
+    @JsonProperty( value = "messages" )
+    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
+    public List<MessageConversation> getMessageConversations()
+    {
+        return messageConversations;
+    }
+
+    public void setMessageConversations( List<MessageConversation> messageConversations )
+    {
+        this.messageConversations = messageConversations;
+    }
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageService.java	2011-12-13 15:40:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageService.java	2011-12-16 09:48:40 +0000
@@ -39,6 +39,7 @@
 public interface MessageService
 {
     final String ID = MessageService.class.getName();
+
     final String META_USER_AGENT = "User-agent: ";
     
     int sendMessage( String subject, String text, String metaData, Set<User> users );
@@ -52,8 +53,10 @@
     void updateMessageConversation( MessageConversation conversation );
     
     int sendCompletenessMessage( CompleteDataSetRegistration registration );
-    
+
     MessageConversation getMessageConversation( int id );
+
+    MessageConversation getMessageConversation( String uid );
     
     long getUnreadMessageConversationCount();
     

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/UserMessage.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/UserMessage.java	2011-11-01 11:34:58 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/UserMessage.java	2011-12-16 09:48:40 +0000
@@ -27,21 +27,29 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.hisp.dhis.common.Dxf2Namespace;
+import org.hisp.dhis.user.User;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
 import java.util.UUID;
 
-import org.hisp.dhis.user.User;
-
 /**
  * @author Lars Helge Overland
  */
+@XmlRootElement( name = "userMessage", namespace = Dxf2Namespace.NAMESPACE )
+@XmlAccessorType( value = XmlAccessType.NONE )
 public class UserMessage
 {
     private int id;
-    
+
     private String key;
-    
+
     private User user;
-    
+
     private boolean read;
 
     public UserMessage()
@@ -62,7 +70,7 @@
         this.user = user;
         this.read = read;
     }
-    
+
     public int getId()
     {
         return id;
@@ -73,6 +81,8 @@
         this.id = id;
     }
 
+    @XmlElement
+    @JsonProperty
     public String getKey()
     {
         return key;
@@ -83,6 +93,8 @@
         this.key = key;
     }
 
+    @XmlElement
+    @JsonProperty
     public User getUser()
     {
         return user;
@@ -93,6 +105,8 @@
         this.user = user;
     }
 
+    @XmlElement
+    @JsonProperty
     public boolean isRead()
     {
         return read;
@@ -116,22 +130,22 @@
         {
             return true;
         }
-        
+
         if ( object == null )
         {
             return false;
         }
-        
+
         if ( getClass() != object.getClass() )
         {
             return false;
         }
-        
+
         final UserMessage other = (UserMessage) object;
-        
+
         return key.equals( other.key );
     }
-    
+
     @Override
     public String toString()
     {

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java	2011-12-13 15:58:02 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java	2011-12-16 09:48:40 +0000
@@ -27,10 +27,6 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.hisp.dhis.configuration.ConfigurationService;
@@ -41,13 +37,17 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 /**
  * @author Lars Helge Overland
  */
 @Transactional
 public class DefaultMessageService
     implements MessageService
-{    
+{
     private static final Log log = LogFactory.getLog( DefaultMessageService.class );
 
     // -------------------------------------------------------------------------
@@ -62,19 +62,19 @@
     }
 
     private CurrentUserService currentUserService;
-    
+
     public void setCurrentUserService( CurrentUserService currentUserService )
     {
         this.currentUserService = currentUserService;
     }
-    
+
     private ConfigurationService configurationService;
 
     public void setConfigurationService( ConfigurationService configurationService )
     {
         this.configurationService = configurationService;
     }
-    
+
     private List<MessageSender> messageSenders;
 
     @Autowired
@@ -82,9 +82,9 @@
     {
         this.messageSenders = messageSenders;
 
-        log.info( "Found the following message senders: " + messageSenders );        
+        log.info( "Found the following message senders: " + messageSenders );
     }
-    
+
     // -------------------------------------------------------------------------
     // MessageService implementation
     // -------------------------------------------------------------------------
@@ -103,31 +103,31 @@
         }
 
         User sender = currentUserService.getCurrentUser();
-        
+
         if ( sender != null )
         {
             users.add( sender );
         }
-        
+
         // ---------------------------------------------------------------------
         // Instantiate message, content and user messages
         // ---------------------------------------------------------------------
 
         MessageConversation conversation = new MessageConversation( subject, sender );
-        
+
         conversation.addMessage( new Message( text, metaData, sender ) );
-        
+
         for ( User user : users )
         {
             boolean read = user != null && user.equals( sender );
-            
-            conversation.addUserMessage( new UserMessage( user, read ) );        
+
+            conversation.addUserMessage( new UserMessage( user, read ) );
         }
-        
+
         int id = saveMessageConversation( conversation );
-        
+
         invokeMessageSenders( subject, text, sender, users );
-        
+
         return id;
     }
 
@@ -135,17 +135,17 @@
     {
         return sendMessage( subject, text, metaData, new HashSet<User>() );
     }
-    
+
     public void sendReply( MessageConversation conversation, String text, String metaData )
     {
         User sender = currentUserService.getCurrentUser();
-        
+
         Message message = new Message( text, metaData, sender );
-        
+
         conversation.markReplied( sender, message );
-        
+
         updateMessageConversation( conversation );
-        
+
         invokeMessageSenders( conversation.getSubject(), text, sender, conversation.getUsers() );
     }
 
@@ -159,53 +159,58 @@
 
             //TODO i18n and string externalization            
             String subject = "Form registered as complete";
-            String text = "The form " + registration.getDataSet() + " was registered as complete for period " + 
+            String text = "The form " + registration.getDataSet() + " was registered as complete for period " +
                 registration.getPeriod().getName() + " and organisation unit " + registration.getSource();
-            
+
             MessageConversation conversation = new MessageConversation( subject, sender );
-            
+
             conversation.addMessage( new Message( text, null, sender ) );
-            
+
             for ( User user : userGroup.getMembers() )
             {
-                conversation.addUserMessage( new UserMessage( user ) );        
+                conversation.addUserMessage( new UserMessage( user ) );
             }
-            
+
             int id = saveMessageConversation( conversation );
-            
+
             invokeMessageSenders( subject, text, sender, userGroup.getMembers() );
-            
+
             return id;
         }
-        
+
         return 0;
     }
-    
+
     public int saveMessageConversation( MessageConversation conversation )
     {
         return messageConversationStore.save( conversation );
     }
-    
+
     public void updateMessageConversation( MessageConversation conversation )
     {
         messageConversationStore.update( conversation );
     }
-    
+
     public MessageConversation getMessageConversation( int id )
     {
         return messageConversationStore.get( id );
     }
-        
+
+    public MessageConversation getMessageConversation( String uid )
+    {
+        return messageConversationStore.getByUid( uid );
+    }
+
     public long getUnreadMessageConversationCount()
     {
         return messageConversationStore.getUnreadUserMessageConversationCount( currentUserService.getCurrentUser() );
     }
-    
+
     public long getUnreadMessageConversationCount( User user )
     {
         return messageConversationStore.getUnreadUserMessageConversationCount( user );
     }
-    
+
     public List<MessageConversation> getMessageConversations( int first, int max )
     {
         return messageConversationStore.getMessageConversations( currentUserService.getCurrentUser(), first, max );

=== added file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/MessageConversationController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/MessageConversationController.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/MessageConversationController.java	2011-12-16 09:48:40 +0000
@@ -0,0 +1,145 @@
+package org.hisp.dhis.api.controller;
+
+/*
+ * Copyright (c) 2004-2011, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import org.hisp.dhis.api.utils.IdentifiableObjectParams;
+import org.hisp.dhis.api.utils.WebLinkPopulator;
+import org.hisp.dhis.message.MessageConversation;
+import org.hisp.dhis.message.MessageConversations;
+import org.hisp.dhis.message.MessageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+@Controller
+@RequestMapping( value = MessageConversationController.RESOURCE_PATH )
+public class MessageConversationController
+{
+    public static final String RESOURCE_PATH = "/messageConversations";
+
+    @Autowired
+    private MessageService messageService;
+
+    //-------------------------------------------------------------------------------------------------------
+    // GET
+    //-------------------------------------------------------------------------------------------------------
+
+    @RequestMapping( method = RequestMethod.GET )
+    public String getMessageConversations( IdentifiableObjectParams params, Model model, HttpServletRequest request )
+    {
+        MessageConversations messageConversations = new MessageConversations();
+        messageConversations.setMessageConversations( new ArrayList<MessageConversation>( messageService.getMessageConversations( 0, 300 ) ) );
+
+        if ( params.hasLinks() )
+        {
+            WebLinkPopulator listener = new WebLinkPopulator( request );
+            listener.addLinks( messageConversations );
+        }
+
+        model.addAttribute( "model", messageConversations );
+
+        return "messages";
+    }
+
+    @RequestMapping( value = "/{uid}", method = RequestMethod.GET )
+    public String getMessageConversation( @PathVariable( "uid" ) String uid, IdentifiableObjectParams params, Model model, HttpServletRequest request )
+    {
+        MessageConversation messageConversation = messageService.getMessageConversation( uid );
+
+        if ( params.hasLinks() )
+        {
+            WebLinkPopulator listener = new WebLinkPopulator( request );
+            listener.addLinks( messageConversation );
+        }
+
+        model.addAttribute( "model", messageConversation );
+
+        return "message";
+    }
+
+    //-------------------------------------------------------------------------------------------------------
+    // POST
+    //-------------------------------------------------------------------------------------------------------
+
+    @RequestMapping( method = RequestMethod.POST, headers = {"Content-Type=application/xml, text/xml"} )
+    @ResponseStatus( value = HttpStatus.CREATED )
+    public void postMessageConversationXML( HttpServletResponse response, InputStream input ) throws Exception
+    {
+        throw new HttpRequestMethodNotSupportedException( RequestMethod.POST.toString() );
+    }
+
+    @RequestMapping( method = RequestMethod.POST, headers = {"Content-Type=application/json"} )
+    @ResponseStatus( value = HttpStatus.CREATED )
+    public void postMessageConversationJSON( HttpServletResponse response, InputStream input ) throws Exception
+    {
+        throw new HttpRequestMethodNotSupportedException( RequestMethod.POST.toString() );
+    }
+
+    //-------------------------------------------------------------------------------------------------------
+    // PUT
+    //-------------------------------------------------------------------------------------------------------
+
+    @RequestMapping( value = "/{uid}", method = RequestMethod.PUT, headers = {"Content-Type=application/xml, text/xml"} )
+    @ResponseStatus( value = HttpStatus.NO_CONTENT )
+    public void putMessageConversationXML( @PathVariable( "uid" ) String uid, InputStream input ) throws Exception
+    {
+        throw new HttpRequestMethodNotSupportedException( RequestMethod.DELETE.toString() );
+    }
+
+    @RequestMapping( value = "/{uid}", method = RequestMethod.PUT, headers = {"Content-Type=application/json"} )
+    @ResponseStatus( value = HttpStatus.NO_CONTENT )
+    public void putMessageConversationJSON( @PathVariable( "uid" ) String uid, InputStream input ) throws Exception
+    {
+        throw new HttpRequestMethodNotSupportedException( RequestMethod.PUT.toString() );
+    }
+
+    //-------------------------------------------------------------------------------------------------------
+    // DELETE
+    //-------------------------------------------------------------------------------------------------------
+
+    @RequestMapping( value = "/{uid}", method = RequestMethod.DELETE )
+    @ResponseStatus( value = HttpStatus.NO_CONTENT )
+    public void deleteMessageConversation( @PathVariable( "uid" ) String uid ) throws Exception
+    {
+        throw new HttpRequestMethodNotSupportedException( RequestMethod.DELETE.toString() );
+    }
+}