← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 7990: Added SMPP gateway. Refactoring of the parser.

 

------------------------------------------------------------
revno: 7990
committer: Magnus Korvald <korvald@xxxxxxxxxxx>
branch nick: trunk
timestamp: Thu 2012-08-30 14:47:05 +0200
message:
  Added SMPP gateway. Refactoring of the parser. 
removed:
  dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/IParser.java
  dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSParserKeyValue.java
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SMPPGatewayConfig.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/SMPPInboundNotification.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserManager.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserType.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/SMSParserException.java
  dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/
  dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/DefaultParserManager.java
  dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/IParser.java
  dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/SMSParserKeyValue.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/UpdateSMPPGateWayConfigAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/validate_javascript.vm
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/smscommand/SMSCommand.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/smscommand/SMSCommand.hbm.xml
  dhis-2/dhis-services/dhis-service-sms/pom.xml
  dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/inbound/DefaultInboundSmsService.java
  dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/smslib/GateWayFactory.java
  dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/smslib/SmsLibService.java
  dhis-2/dhis-services/dhis-service-sms/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/GetSmsConfigurationAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/CreateSMSCommandForm.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/EditSMSCommandForm.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/SMSCommandAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/org/hisp/dhis/mobile/i18n_module.properties
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/struts.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/javascript/gateway.js
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/edit-sms-command.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/new-sms-command.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/sms-commands.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/updateGateway.vm
  dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/action/MenuAction.java
  dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSInput.java
  dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml


--
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/sms/config/SMPPGatewayConfig.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SMPPGatewayConfig.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SMPPGatewayConfig.java	2012-08-30 12:47:05 +0000
@@ -0,0 +1,69 @@
+package org.hisp.dhis.sms.config;
+
+public class SMPPGatewayConfig
+    extends SmsGatewayConfig
+{
+
+    private static final long serialVersionUID = 780006289158356660L;
+
+    private String address;
+
+    private int port;
+
+    private String username;
+
+    private String password;
+
+    public String getUsername()
+    {
+        return username;
+    }
+
+    public void setUsername( String username )
+    {
+        this.username = username;
+    }
+
+    public String getPassword()
+    {
+        return password;
+    }
+
+    public void setPassword( String password )
+    {
+        this.password = password;
+    }
+
+    @Override
+    public boolean isInbound()
+    {
+        return true;
+    }
+
+    @Override
+    public boolean isOutbound()
+    {
+        return true;
+    }
+
+    public int getPort()
+    {
+        return port;
+    }
+
+    public void setPort( int port )
+    {
+        this.port = port;
+    }
+
+    public String getAddress()
+    {
+        return address;
+    }
+
+    public void setAddress( String address )
+    {
+        this.address = address;
+    }
+
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/SMPPInboundNotification.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/SMPPInboundNotification.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/SMPPInboundNotification.java	2012-08-30 12:47:05 +0000
@@ -0,0 +1,47 @@
+package org.hisp.dhis.sms.incoming;
+
+import org.smslib.AGateway;
+import org.smslib.IInboundMessageNotification;
+import org.smslib.InboundMessage;
+import org.smslib.Message.MessageTypes;
+
+public class SMPPInboundNotification
+    implements IInboundMessageNotification
+{
+    
+    private IncomingSmsService incomingSmsService;
+
+    @Override
+    public void process( AGateway gateway, MessageTypes msgType, InboundMessage msg )
+    {
+
+        System.out.println( msg );
+
+        IncomingSms incomingSms = new IncomingSms();
+
+        incomingSms.setOriginator( msg.getOriginator() );
+
+        incomingSms.setEncoding( SmsMessageEncoding.ENC7BIT );
+
+        incomingSms.setSentDate( msg.getDate() );
+
+        incomingSms.setReceivedDate( msg.getDate() );
+
+        incomingSms.setText( msg.getText() );
+
+        incomingSms.setGatewayId( msg.getGatewayId() );
+
+        incomingSms.setStatus( SmsMessageStatus.PROCESSED );
+
+        incomingSms.setStatusMessage( "imported" );
+        
+        incomingSmsService.save( incomingSms );
+
+    }
+
+    public void setIncomingSmsService( IncomingSmsService incomingSmsService )
+    {
+        this.incomingSmsService = incomingSmsService;
+    }
+
+}

=== added directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse'
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserManager.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserManager.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserManager.java	2012-08-30 12:47:05 +0000
@@ -0,0 +1,7 @@
+package org.hisp.dhis.sms.parse;
+
+public interface ParserManager
+{
+    public void parse( String sender, String message )
+        throws SMSParserException;
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserType.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserType.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserType.java	2012-08-30 12:47:05 +0000
@@ -0,0 +1,6 @@
+package org.hisp.dhis.sms.parse;
+
+public enum ParserType
+{
+    KEY_VALUE_PARSER
+}

=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/SMSParserException.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/SMSParserException.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/SMSParserException.java	2012-08-30 12:47:05 +0000
@@ -0,0 +1,13 @@
+package org.hisp.dhis.sms.parse;
+
+public class SMSParserException
+    extends RuntimeException
+{
+
+    private static final long serialVersionUID = -8088120989819092567L;
+
+    SMSParserException(String message){
+        super(message);
+    }
+    
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/smscommand/SMSCommand.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/smscommand/SMSCommand.java	2012-08-24 12:14:49 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/smscommand/SMSCommand.java	2012-08-30 12:47:05 +0000
@@ -1,131 +1,184 @@
 package org.hisp.dhis.smscommand;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 import java.util.Set;
 
 import org.hisp.dhis.dataset.DataSet;
+import org.hisp.dhis.sms.parse.ParserType;
 
-public class SMSCommand {
+public class SMSCommand
+{
 
     private int id; // id for this element
+
     private String name;
-    
+
     private String parser; // message type
+
+    private ParserType parserType;
+
     private String separator;
 
-    private DataSet dataset; 
+    private DataSet dataset;
+
     private Set<SMSCode> codes;
-    private String codeSeparator; 
-    
+
+    private String codeSeparator;
+
     private String defaultMessage;
 
-    public SMSCommand(String name, String parser, String separator, DataSet dataset, Set<SMSCode> codes,
-            String codeSeparator) {
-        this.name = name;
-        this.parser = parser;
-        this.separator = separator;
-        this.dataset = dataset;
-        this.codes = codes;
-        this.setCodeSeparator(codeSeparator);
-    }
-
-    public SMSCommand(String name, String parser, String separator, DataSet dataset, Set<SMSCode> codes) {
-        this.name = name;
-        this.parser = parser;
-        this.separator = separator;
-        this.dataset = dataset;
-        this.codes = codes;
-    }
-
-
-
-    public SMSCommand(String parser, String name, DataSet dataset, Set<SMSCode> codes) {
-        this.parser = parser;
-        this.name = name;
-        this.dataset = dataset;
-        this.codes = codes;
-    }
-
-    public SMSCommand(String parser, String name, DataSet dataset) {
-        this.parser = parser;
-        this.name = name;
-        this.dataset = dataset;
-    }
-
-    public SMSCommand(String name, String parser) {
-        this.name = name;
-        this.parser = parser;
-    }
-
-    public SMSCommand() {
-
-    }
-
-    public String getName() {
+    
+
+    public SMSCommand( String name, String parser, ParserType parserType, String separator, DataSet dataset,
+        Set<SMSCode> codes, String codeSeparator, String defaultMessage )
+    {
+        super();
+        this.name = name;
+        this.parser = parser;
+        this.parserType = parserType;
+        this.separator = separator;
+        this.dataset = dataset;
+        this.codes = codes;
+        this.codeSeparator = codeSeparator;
+        this.defaultMessage = defaultMessage;
+    }
+
+    public SMSCommand( String name, String parser, String separator, DataSet dataset, Set<SMSCode> codes,
+        String codeSeparator )
+    {
+        this.name = name;
+        this.parser = parser;
+        this.separator = separator;
+        this.dataset = dataset;
+        this.codes = codes;
+        this.setCodeSeparator( codeSeparator );
+    }
+
+    public SMSCommand( String name, String parser, String separator, DataSet dataset, Set<SMSCode> codes )
+    {
+        this.name = name;
+        this.parser = parser;
+        this.separator = separator;
+        this.dataset = dataset;
+        this.codes = codes;
+    }
+
+    public SMSCommand( String parser, String name, DataSet dataset, Set<SMSCode> codes )
+    {
+        this.parser = parser;
+        this.name = name;
+        this.dataset = dataset;
+        this.codes = codes;
+    }
+
+    public SMSCommand( String parser, String name, DataSet dataset )
+    {
+        this.parser = parser;
+        this.name = name;
+        this.dataset = dataset;
+    }
+
+    public SMSCommand( String name, String parser )
+    {
+        this.name = name;
+        this.parser = parser;
+    }
+
+    public SMSCommand()
+    {
+
+    }
+
+    public String getName()
+    {
         return name;
     }
 
-    public void setName(String name) {
+    public void setName( String name )
+    {
         this.name = name;
     }
 
-    public String getParser() {
+    public String getParser()
+    {
         return parser;
     }
 
-    public void setParser(String parser) {
+    public void setParser( String parser )
+    {
         this.parser = parser;
     }
 
-    public int getId() {
+    public int getId()
+    {
         return id;
     }
 
-    public void setId(int id) {
+    public void setId( int id )
+    {
         this.id = id;
     }
 
-    public DataSet getDataset() {
+    public DataSet getDataset()
+    {
         return dataset;
     }
 
-    public void setDataset(DataSet dataset) {
+    public void setDataset( DataSet dataset )
+    {
         this.dataset = dataset;
     }
 
-    public Set<SMSCode> getCodes() {
+    public Set<SMSCode> getCodes()
+    {
         return codes;
     }
 
-
-    public void setCodes(Set<SMSCode> codes) {
+    public void setCodes( Set<SMSCode> codes )
+    {
         this.codes = codes;
     }
 
-    public String getSeparator() {
+    public String getSeparator()
+    {
         return separator;
     }
 
-    public void setSeparator(String separator) {
+    public void setSeparator( String separator )
+    {
         this.separator = separator;
     }
 
-    public String getCodeSeparator() {
+    public String getCodeSeparator()
+    {
         return codeSeparator;
     }
 
-    public void setCodeSeparator(String codeSeparator) {
+    public void setCodeSeparator( String codeSeparator )
+    {
         this.codeSeparator = codeSeparator;
     }
 
-    public String getDefaultMessage() {
+    public String getDefaultMessage()
+    {
         return defaultMessage;
     }
 
-    public void setDefaultMessage(String defaultMessage) {
+    public void setDefaultMessage( String defaultMessage )
+    {
         this.defaultMessage = defaultMessage;
     }
 
+    public ParserType getParserType()
+    {
+        if(parserType == null){
+            return ParserType.KEY_VALUE_PARSER;
+        }
+        return parserType;
+    }
+
+    public void setParserType( ParserType parserType )
+    {
+        this.parserType = parserType;
+    }
+
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/smscommand/SMSCommand.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/smscommand/SMSCommand.hbm.xml	2012-08-22 06:31:11 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/smscommand/SMSCommand.hbm.xml	2012-08-30 12:47:05 +0000
@@ -12,7 +12,16 @@
       <generator class="increment" />
     </id>
     <property name="name" type="text" />
+    
     <property name="parser" type="text" />
+    
+     <property name="parserType">
+      <type name="org.hibernate.type.EnumType">
+         <param name="enumClass">org.hisp.dhis.sms.parse.ParserType</param>
+      </type>
+   </property>
+    
+    
     <property name="separator" type="text" />
     <property name="codeSeparator" type="text" />
     <property name="defaultMessage" type="text" />

=== modified file 'dhis-2/dhis-services/dhis-service-sms/pom.xml'
--- dhis-2/dhis-services/dhis-service-sms/pom.xml	2012-08-21 13:12:22 +0000
+++ dhis-2/dhis-services/dhis-service-sms/pom.xml	2012-08-30 12:47:05 +0000
@@ -28,18 +28,20 @@
       <groupId>org.hisp.dhis</groupId>
       <artifactId>dhis-service-administration</artifactId>
     </dependency>
-    
-	<!-- SMS -->
-    
+
+    <!-- SMS -->
+
     <dependency>
       <groupId>org.smslib</groupId>
       <artifactId>smslib</artifactId>
     </dependency>
+
     <dependency>
-	  <groupId>org.rxtx</groupId>
-	  <artifactId>rxtx</artifactId>
-	</dependency>
-    
+      <groupId>com.googlecode.jsmpp</groupId>
+      <artifactId>jsmpp</artifactId>
+      <version>2.1.0-RELEASE</version>
+    </dependency>
+
   </dependencies>
 
   <properties>

=== modified file 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/inbound/DefaultInboundSmsService.java'
--- dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/inbound/DefaultInboundSmsService.java	2012-06-06 07:48:54 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/inbound/DefaultInboundSmsService.java	2012-08-30 12:47:05 +0000
@@ -119,6 +119,8 @@
     public void save( IncomingSms incomingSms )
     {
         incomingSmsStore.save( incomingSms );
+        
+        //TODO: run parser ?
     }
 
     @Override

=== added directory 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse'
=== added file 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/DefaultParserManager.java'
--- dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/DefaultParserManager.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/DefaultParserManager.java	2012-08-30 12:47:05 +0000
@@ -0,0 +1,204 @@
+package org.hisp.dhis.sms.parse;
+
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
+import org.hisp.dhis.datavalue.DataValue;
+import org.hisp.dhis.datavalue.DataValueService;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.period.CalendarPeriodType;
+import org.hisp.dhis.period.Period;
+import org.hisp.dhis.sms.outbound.OutboundSms;
+import org.hisp.dhis.sms.outbound.OutboundSmsService;
+import org.hisp.dhis.smscommand.SMSCode;
+import org.hisp.dhis.smscommand.SMSCommand;
+import org.hisp.dhis.smscommand.SMSCommandService;
+import org.hisp.dhis.user.CurrentUserService;
+import org.hisp.dhis.user.User;
+import org.hisp.dhis.user.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Required;
+
+/**
+ * 
+ * @author Christian and Magnus
+ */
+public class DefaultParserManager
+    implements ParserManager
+{
+
+    private CurrentUserService currentUserService;
+
+    private DataValueService dataValueService;
+
+    private UserService userService;
+
+    private SMSCommandService smsCommandService;
+
+    @Autowired
+    private DataElementCategoryService dataElementCategoryService;
+
+    public void parse( String sender, String message )
+        throws SMSParserException
+    {
+
+        OrganisationUnit orgunit = getOrganisationUnit( sender );
+
+        if ( orgunit == null )
+        {
+            throw new SMSParserException( "No user associated with this phone number. Please contact your supervisor." );
+        }
+
+        if ( message.indexOf( " " ) < 1 )
+        {
+            throw new SMSParserException( "No command in SMS" );
+        }
+
+        String commandString = message.substring( 0, message.indexOf( " " ) );
+        message = message.substring( commandString.length() );
+
+        boolean foundCommand = false;
+
+        for ( SMSCommand command : smsCommandService.getSMSCommands() )
+        {
+            if ( command.getName().equalsIgnoreCase( commandString ) )
+            {
+                foundCommand = true;
+                if ( ParserType.KEY_VALUE_PARSER.equals( command.getParserType() ) )
+                {
+                    runKeyValueParser( sender, message, orgunit, command );
+                    break;
+                }
+            }
+        }
+        if ( !foundCommand )
+        {
+            throw new SMSParserException( "Command '" + commandString + "' does not exist" );
+        }
+    }
+
+    private void runKeyValueParser( String sender, String message, OrganisationUnit orgunit, SMSCommand command )
+    {
+        IParser p = new SMSParserKeyValue();
+        if ( !StringUtils.isBlank( command.getSeparator() ) )
+        {
+            p.setSeparator( command.getSeparator() );
+        }
+
+        Map<String, String> parsedMessage = p.parse( message );
+        if ( parsedMessage.isEmpty() )
+        {
+            throw new SMSParserException( command.getDefaultMessage() );
+        }
+
+        for ( SMSCode code : command.getCodes() )
+        {
+            if ( parsedMessage.containsKey( code.getCode().toUpperCase() ) )
+            {
+                storeDataValue( sender, orgunit, parsedMessage, code );
+            }
+        }
+    }
+
+    private void storeDataValue( String sender, OrganisationUnit orgunit, Map<String, String> parsedMessage,
+        SMSCode code )
+    {
+        String upperCaseCode = code.getCode().toUpperCase();
+
+        String storedBy = currentUserService.getCurrentUsername();
+
+        if ( StringUtils.isBlank( storedBy ) )
+        {
+            storedBy = "[unknown] from [" + sender + "]";
+        }
+
+        DataElementCategoryOptionCombo optionCombo = null;
+        optionCombo = dataElementCategoryService.getDataElementCategoryOptionCombo( code.getOptionId() );
+
+        Period period = code.getDataElement().getPeriodType().createPeriod();
+        CalendarPeriodType cpt = (CalendarPeriodType) period.getPeriodType();
+        period = cpt.getPreviousPeriod( period );
+
+        DataValue dv = dataValueService.getDataValue( orgunit, code.getDataElement(), period, optionCombo );
+
+        if ( dv == null )
+        {
+            // New data element
+            DataValue dataVal = new DataValue();
+            dataVal.setOptionCombo( optionCombo );
+            dataVal.setSource( orgunit );
+            dataVal.setDataElement( code.getDataElement() );
+            dataVal.setPeriod( period );
+            dataVal.setComment( "" );
+            dataVal.setTimestamp( new java.util.Date() );
+            dataVal.setStoredBy( storedBy );
+            dataVal.setValue( parsedMessage.get( upperCaseCode ) );
+            dataValueService.addDataValue( dataVal );
+        }
+        else
+        {
+            // Update data element
+            dv.setValue( parsedMessage.get( upperCaseCode ) );
+            dv.setOptionCombo( optionCombo );
+            dataValueService.updateDataValue( dv );
+        }
+    }
+
+    private OrganisationUnit getOrganisationUnit( String sender )
+    {
+        OrganisationUnit orgunit = null;
+        for ( User user : userService.getUsersByPhoneNumber( sender ) )
+        {
+            OrganisationUnit ou = user.getOrganisationUnit();
+
+            // Might be undefined if the user has more than one org.units
+            // "attached"
+            if ( orgunit == null )
+            {
+                orgunit = ou;
+            }
+            else if ( orgunit.getId() == ou.getId() )
+            {
+                // same orgunit, no problem...
+            }
+            else
+            {
+                throw new SMSParserException(
+                    "User is associated with more than one orgunit. Please contact your supervisor." );
+            }
+        }
+        return orgunit;
+    }
+
+    public void setDataElementCategoryService( DataElementCategoryService dataElementCategoryService )
+    {
+        this.dataElementCategoryService = dataElementCategoryService;
+    }
+
+    @Required
+    public void setSmsCommandService( SMSCommandService smsCommandService )
+    {
+        this.smsCommandService = smsCommandService;
+    }
+
+    @Required
+    public void setCurrentUserService( CurrentUserService currentUserService )
+    {
+        this.currentUserService = currentUserService;
+    }
+
+    @Required
+    public void setDataValueService( DataValueService dataValueService )
+    {
+        this.dataValueService = dataValueService;
+    }
+
+    @Required
+    public void setUserService( UserService userService )
+    {
+        this.userService = userService;
+    }
+
+}

=== added file 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/IParser.java'
--- dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/IParser.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/IParser.java	2012-08-30 12:47:05 +0000
@@ -0,0 +1,21 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.hisp.dhis.sms.parse;
+
+import java.util.Map;
+
+/**
+ *
+ * @author Christian
+ */
+public interface IParser {
+    
+    static final String DATA_ENTRY_KEYWORD = "DHISDATAENTRYKEYWORD";
+    
+    public Map<String, String> parse(String sms);
+    
+    public void setSeparator(String separator);
+    
+}

=== added file 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/SMSParserKeyValue.java'
--- dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/SMSParserKeyValue.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/SMSParserKeyValue.java	2012-08-30 12:47:05 +0000
@@ -0,0 +1,49 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.hisp.dhis.sms.parse;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Magnus Korvald
+ */
+public class SMSParserKeyValue
+    implements IParser
+{
+  //= "([a-zA-Z]+)\\s*(\\d+)";
+    private String defaultPattern = "(\\w+)\\s*\\*\\s*([\\w ]+)\\s*(\\*|$)*\\s*";
+    private Pattern pattern = Pattern.compile( defaultPattern );
+
+    @Override
+    public Map<String, String> parse( String sms )
+    {
+
+        HashMap<String, String> output = new HashMap<String, String>();
+
+        Matcher m = pattern.matcher( sms );
+        while ( m.find() )
+        {
+            String key = m.group( 1 );
+            String value = m.group( 2 );
+            System.out.println( "Key: " + key + " Value: " + value );
+            if ( key != null && value != null )
+            {
+                output.put( key.toUpperCase(), value );
+            }
+        }
+
+        return output;
+    }
+
+    public void setSeparator( String separator )
+    {
+        String x = "(\\w+)\\s*" + separator.trim()  + "\\s*(\\d+)";
+        pattern = Pattern.compile( x );
+    }
+
+}

=== modified file 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/smslib/GateWayFactory.java'
--- dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/smslib/GateWayFactory.java	2012-07-24 10:19:04 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/smslib/GateWayFactory.java	2012-08-30 12:47:05 +0000
@@ -32,6 +32,7 @@
 import org.hisp.dhis.sms.config.ClickatellGatewayConfig;
 import org.hisp.dhis.sms.config.GenericHttpGatewayConfig;
 import org.hisp.dhis.sms.config.ModemGatewayConfig;
+import org.hisp.dhis.sms.config.SMPPGatewayConfig;
 import org.hisp.dhis.sms.config.SmsGatewayConfig;
 import org.smslib.AGateway;
 import org.smslib.AGateway.Protocols;
@@ -39,6 +40,9 @@
 import org.smslib.http.BulkSmsHTTPGateway.Regions;
 import org.smslib.http.ClickatellHTTPGateway;
 import org.smslib.modem.SerialModemGateway;
+import org.smslib.smpp.BindAttributes;
+import org.smslib.smpp.BindAttributes.BindType;
+import org.smslib.smpp.jsmpp.JSMPPGateway;
 
 public class GateWayFactory
 {
@@ -60,11 +64,25 @@
         {
             return createModemGateway( (ModemGatewayConfig) config );
         }
+        else if ( config instanceof SMPPGatewayConfig )
+        {
+            return createSMPPGatewayConfig( (SMPPGatewayConfig) config );
+        }
 
         throw new SmsServiceException( "Gateway config of unknown type: " + config.getClass().getName() );
 
     }
 
+    public AGateway createSMPPGatewayConfig( SMPPGatewayConfig config )
+    {
+
+        AGateway gateway = new JSMPPGateway( config.getName(), config.getAddress(), config.getPort(),
+            new BindAttributes( config.getUsername(), config.getPassword(), "cp", BindType.TRANSCEIVER ) );
+        gateway.setInbound( true );
+        gateway.setOutbound( true );
+        return gateway;
+    }
+
     public AGateway createBulkSmsGateway( BulkSmsGatewayConfig config )
     {
         BulkSmsHTTPGateway gateway = new BulkSmsHTTPGateway( "bulksms.http.1", config.getUsername(),

=== modified file 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/smslib/SmsLibService.java'
--- dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/smslib/SmsLibService.java	2012-06-04 06:37:01 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/smslib/SmsLibService.java	2012-08-30 12:47:05 +0000
@@ -39,12 +39,14 @@
 import org.hisp.dhis.sms.config.BulkSmsGatewayConfig;
 import org.hisp.dhis.sms.config.ClickatellGatewayConfig;
 import org.hisp.dhis.sms.config.GenericHttpGatewayConfig;
+import org.hisp.dhis.sms.config.SMPPGatewayConfig;
 import org.hisp.dhis.sms.config.SmsConfiguration;
 import org.hisp.dhis.sms.config.SmsGatewayConfig;
 import org.hisp.dhis.sms.outbound.OutboundSms;
 import org.hisp.dhis.sms.outbound.OutboundSmsTransportService;
 import org.smslib.AGateway;
 import org.smslib.GatewayException;
+import org.smslib.IInboundMessageNotification;
 import org.smslib.IOutboundMessageNotification;
 import org.smslib.OutboundMessage;
 import org.smslib.SMSLibException;
@@ -72,10 +74,15 @@
 
     private final String MODEM_GATEWAY = "modem_gw";
 
+    private final String SMPP_GATEWAY = "smpp_gw";
+
+    private IInboundMessageNotification smppInboundMessageNotification;
+
     // -------------------------------------------------------------------------
     // Implementation methods
     // -------------------------------------------------------------------------
 
+
     @Override
     public boolean isEnabled()
     {
@@ -272,6 +279,11 @@
                     {
                         gatewayMap.put( HTTP_GATEWAY, gateway.getGatewayId() );
                     }
+                    else if ( gatewayConfig instanceof SMPPGatewayConfig )
+                    {
+                        gatewayMap.put( SMPP_GATEWAY, gateway.getGatewayId() );
+                 //       Service.getInstance().setInboundMessageNotification( new InboundNotification() );
+                    }
                     else
                     {
                         gatewayMap.put( MODEM_GATEWAY, gateway.getGatewayId() );
@@ -298,6 +310,11 @@
             try
             {
                 getService().startService();
+                if ( gatewayMap.containsKey( SMPP_GATEWAY ) )
+                {
+                    getService().setInboundMessageNotification( smppInboundMessageNotification );
+                }
+
             }
             catch ( SMSLibException e )
             {
@@ -414,6 +431,12 @@
             log.debug( "Sent message through gateway " + gateway.getGatewayId() + ": " + msg );
         }
     }
+    
+    public void setSmppInboundMessageNotification( IInboundMessageNotification smppInboundMessageNotification )
+    {
+        this.smppInboundMessageNotification = smppInboundMessageNotification;
+    }
+
 
     @Override
     public List<OutboundSms> getAllOutboundSms()

=== modified file 'dhis-2/dhis-services/dhis-service-sms/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-sms/src/main/resources/META-INF/dhis/beans.xml	2012-05-31 09:58:44 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/main/resources/META-INF/dhis/beans.xml	2012-08-30 12:47:05 +0000
@@ -1,39 +1,51 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans";
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-       xsi:schemaLocation="
+<beans xmlns="http://www.springframework.org/schema/beans"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+  xsi:schemaLocation="
 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd";>
 
   <bean id="org.hisp.dhis.sms.outbound.SmsConfigurationManager" class="org.hisp.dhis.sms.SmsConfigurationManagerImpl" />
-  
+
   <!-- Outbound SMS service -->
 
   <bean id="outboundSmsStore" class="org.hisp.dhis.sms.outbound.HibernateOutboundSmsStore">
     <property name="sessionFactory" ref="sessionFactory" />
   </bean>
-  
+
   <bean id="org.hisp.dhis.sms.outbound.OutboundSmsService" class="org.hisp.dhis.sms.outbound.OutboundSmsServiceImpl" />
-  
-  <!--  Only for testing! OutboundSmsService stub just logging invocations, replacing the default one or use as the OutboundSmsTransportService..  -->
-  <!--  <bean id="TestOutboundSmsService" class="org.hisp.dhis.sms.outbound.TestOutboundSmsService" /> -->
-
-  <bean id="smsLibService" class="org.hisp.dhis.sms.smslib.SmsLibService" />
-
-  <!--  SMS Message sender -->
+
+  <!-- Only for testing! OutboundSmsService stub just logging invocations, replacing the default one or use as the OutboundSmsTransportService.. -->
+  <!-- <bean id="TestOutboundSmsService" class="org.hisp.dhis.sms.outbound.TestOutboundSmsService" /> -->
+
+  <bean id="smsLibService" class="org.hisp.dhis.sms.smslib.SmsLibService">
+    <property name="smppInboundMessageNotification" ref="org.hisp.dhis.sms.incoming.SMPPInboundNotification" />
+  </bean>
+
+  <bean id="org.hisp.dhis.sms.incoming.SMPPInboundNotification" class="org.hisp.dhis.sms.incoming.SMPPInboundNotification">
+    <property name="incomingSmsService" ref="org.hisp.dhis.sms.incoming.IncomingSmsService" />
+  </bean>
+  <!-- SMS Message sender -->
 
   <bean id="org.hisp.dhis.sms.outbound.SmsMessageSender" class="org.hisp.dhis.sms.outbound.SmsMessageSender">
     <property name="outboundSmsService" ref="org.hisp.dhis.sms.outbound.OutboundSmsService" />
     <property name="userService" ref="org.hisp.dhis.user.UserService" />
   </bean>
-  
+
   <!-- Inbound SMS service -->
-  
+
   <bean id="org.hisp.dhis.sms.incoming.IncomingSmsStore" class="org.hisp.dhis.sms.inbound.HibernateIncomingSmsStore">
-  	<property name="sessionFactory" ref="sessionFactory" />
+    <property name="sessionFactory" ref="sessionFactory" />
   </bean>
-  
+
   <bean id="org.hisp.dhis.sms.incoming.IncomingSmsService" class="org.hisp.dhis.sms.inbound.DefaultInboundSmsService">
-  	<property name="incomingSmsStore" ref="org.hisp.dhis.sms.incoming.IncomingSmsStore"/>
-  </bean>
-  
+    <property name="incomingSmsStore" ref="org.hisp.dhis.sms.incoming.IncomingSmsStore" />
+  </bean>
+
+  <bean id="org.hisp.dhis.sms.parse.DefaultParserManager" class="org.hisp.dhis.sms.parse.DefaultParserManager">
+    <property name="userService" ref="org.hisp.dhis.user.UserService" />
+    <property name="smsCommandService" ref="smsCommandService" />
+    <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
+    <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService" />
+  </bean>
+
+
 </beans>

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/GetSmsConfigurationAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/GetSmsConfigurationAction.java	2012-08-14 09:50:07 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/GetSmsConfigurationAction.java	2012-08-30 12:47:05 +0000
@@ -34,6 +34,7 @@
 import org.hisp.dhis.sms.config.BulkSmsGatewayConfig;
 import org.hisp.dhis.sms.config.ClickatellGatewayConfig;
 import org.hisp.dhis.sms.config.ModemGatewayConfig;
+import org.hisp.dhis.sms.config.SMPPGatewayConfig;
 import org.hisp.dhis.sms.config.SmsConfiguration;
 import org.hisp.dhis.sms.config.SmsGatewayConfig;
 import org.hisp.dhis.sms.outbound.OutboundSmsTransportService;
@@ -124,6 +125,13 @@
         return httpIndex;
     }
 
+    public Integer smppIndex;
+
+    public Integer getSmppIndex()
+    {
+        return smppIndex;
+    }
+
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
@@ -131,7 +139,7 @@
     public String execute()
         throws Exception
     {
-        
+
         smsServiceStatus = smsLibService.getServiceStatus();
 
         smsConfig = smsConfigurationManager.getSmsConfiguration();
@@ -158,6 +166,10 @@
                 {
                     modemIndex = index;
                 }
+                else if ( gw instanceof SMPPGatewayConfig )
+                {
+                    smppIndex = index;
+                }
                 else
                 {
                     httpIndex = index;

=== added file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/UpdateSMPPGateWayConfigAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/UpdateSMPPGateWayConfigAction.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/UpdateSMPPGateWayConfigAction.java	2012-08-30 12:47:05 +0000
@@ -0,0 +1,145 @@
+package org.hisp.dhis.mobile.action;
+
+/*
+ * Copyright (c) 2004-2012, 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.sms.SmsConfigurationManager;
+import org.hisp.dhis.sms.config.SMPPGatewayConfig;
+import org.hisp.dhis.sms.config.SmsConfiguration;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+
+public class UpdateSMPPGateWayConfigAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private SmsConfigurationManager smsConfigurationManager;
+
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+
+    private String name;
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    private String password;
+
+    public void setPassword( String password )
+    {
+        this.password = password;
+    }
+
+    private String username;
+
+    public void setUsername( String username )
+    {
+        this.username = username;
+    }
+
+    private String gatewayType;
+
+    public void setGatewayType( String gatewayType )
+    {
+        this.gatewayType = gatewayType;
+    }
+
+    private int port;
+
+    public void setPort( int port )
+    {
+        this.port = port;
+    }
+
+    private String address;
+
+    public void setAddress( String address )
+    {
+        this.address = address;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        if ( gatewayType != null && gatewayType.equals( "smpp_gw" ) )
+        {
+            SmsConfiguration config = smsConfigurationManager.getSmsConfiguration();
+
+            if ( config != null )
+            {
+                SMPPGatewayConfig gatewayConfig = (SMPPGatewayConfig) smsConfigurationManager
+                    .checkInstanceOfGateway( SMPPGatewayConfig.class );
+
+                int index = -1;
+
+                if ( gatewayConfig == null )
+                {
+                    gatewayConfig = new SMPPGatewayConfig();
+                }
+                else
+                {
+                    index = config.getGateways().indexOf( gatewayConfig );
+                }
+
+                gatewayConfig.setName( name );
+                gatewayConfig.setPassword( password );
+                gatewayConfig.setUsername( username );
+                gatewayConfig.setAddress( address );
+                gatewayConfig.setPort( port  );
+                if ( index >= 0 )
+                {
+                    config.getGateways().set( index, gatewayConfig );
+                }
+                else
+                {
+                    config.getGateways().add( gatewayConfig );
+                }
+
+                smsConfigurationManager.updateSmsConfiguration( config );
+            }
+        }
+
+        return SUCCESS;
+    }
+}

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/CreateSMSCommandForm.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/CreateSMSCommandForm.java	2012-06-13 08:44:07 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/CreateSMSCommandForm.java	2012-08-30 12:47:05 +0000
@@ -2,65 +2,103 @@
 
 import org.hisp.dhis.dataset.DataSet;
 import org.hisp.dhis.dataset.DataSetService;
+import org.hisp.dhis.sms.parse.ParserType;
 import org.hisp.dhis.smscommand.SMSCommand;
 import org.hisp.dhis.smscommand.SMSCommandService;
 
 import com.opensymphony.xwork2.Action;
 
-public class CreateSMSCommandForm implements Action {
+public class CreateSMSCommandForm
+    implements Action
+{
 
     private SMSCommandService smsCommandService;
+
     private DataSetService dataSetService;
-    
+
     private String name;
+
     private String parser;
-    private int selectedDataSetID; //
-    
+
+    private ParserType parserType;
+    
+    private int selectedDataSetID; 
+    
+    
+
     @Override
-    public String execute() throws Exception {
-        DataSet dataset = getDataSetService().getDataSet(getSelectedDataSetID());
-        smsCommandService.save(new SMSCommand(parser,name,dataset));
+    public String execute()
+        throws Exception
+    {
+        DataSet dataset = getDataSetService().getDataSet( getSelectedDataSetID() );
+        
+        SMSCommand command = new SMSCommand();
+        command.setName( name );
+        command.setDataset( dataset );
+        command.setParserType( parserType );
+        
+        smsCommandService.save( command );
         return SUCCESS;
     }
 
-    public SMSCommandService getSmsCommandService() {
+    public SMSCommandService getSmsCommandService()
+    {
         return smsCommandService;
     }
 
-    public void setSmsCommandService(SMSCommandService smsCommandService) {
+    public void setSmsCommandService( SMSCommandService smsCommandService )
+    {
         this.smsCommandService = smsCommandService;
     }
 
-    public String getName() {
+    public String getName()
+    {
         return name;
     }
 
-    public void setName(String name) {
+    public void setName( String name )
+    {
         this.name = name;
     }
 
-    public String getParser() {
+    public String getParser()
+    {
         return parser;
     }
 
-    public void setParser(String parser) {
+    public void setParser( String parser )
+    {
         this.parser = parser;
     }
 
-    public int getSelectedDataSetID() {
+    public int getSelectedDataSetID()
+    {
         return selectedDataSetID;
     }
 
-    public void setSelectedDataSetID(int selectedDataSetID) {
+    public void setSelectedDataSetID( int selectedDataSetID )
+    {
         this.selectedDataSetID = selectedDataSetID;
     }
 
-    public DataSetService getDataSetService() {
+    public DataSetService getDataSetService()
+    {
         return dataSetService;
     }
 
-    public void setDataSetService(DataSetService dataSetService) {
+    public void setDataSetService( DataSetService dataSetService )
+    {
         this.dataSetService = dataSetService;
     }
 
+    public ParserType getParserType()
+    {
+        return parserType;
+    }
+
+    public void setParserType( ParserType parserType )
+    {
+        this.parserType = parserType;
+    }
+
 }

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/EditSMSCommandForm.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/EditSMSCommandForm.java	2012-08-22 06:31:11 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/EditSMSCommandForm.java	2012-08-30 12:47:05 +0000
@@ -180,6 +180,7 @@
     {
         this.dataElementService = dataElementService;
     }
+    
 
     public String getCodeSeparator()
     {
@@ -198,4 +199,5 @@
     public void setDefaultMessage(String defaultMessage) {
         this.defaultMessage = defaultMessage;
     }
+
 }
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/SMSCommandAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/SMSCommandAction.java	2012-08-24 12:14:49 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/SMSCommandAction.java	2012-08-30 12:47:05 +0000
@@ -12,6 +12,7 @@
 import org.hisp.dhis.dataelement.comparator.DataElementSortOrderComparator;
 import org.hisp.dhis.dataset.DataSet;
 import org.hisp.dhis.dataset.DataSetService;
+import org.hisp.dhis.sms.parse.ParserType;
 import org.hisp.dhis.smscommand.SMSCode;
 import org.hisp.dhis.smscommand.SMSCommandService;
 import org.hisp.dhis.smscommand.SMSCommand;
@@ -54,9 +55,9 @@
             DataSet d = getSMSCommand().getDataset();
             if ( d != null )
             {
-                List<DataElement> dataElements = new ArrayList<DataElement>( d.getDataElements() );
-                Collections.sort( dataElements, new DataElementSortOrderComparator() );
-                return dataElements;
+                List<DataElement> x = new ArrayList<DataElement>( d.getDataElements() );
+                Collections.sort( x, new DataElementSortOrderComparator() );
+                return x;
             }
         }
 
@@ -124,5 +125,9 @@
     {
         this.codes = codes;
     }
+    
+    public ParserType[] getParserType(){       
+        return ParserType.values();
+    }
 
 }

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/org/hisp/dhis/mobile/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/org/hisp/dhis/mobile/i18n_module.properties	2012-08-24 12:14:49 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/org/hisp/dhis/mobile/i18n_module.properties	2012-08-30 12:47:05 +0000
@@ -133,15 +133,20 @@
 j2me_client_update_config=J2ME Client Update Configuration
 auto_update_client=Automatic update for J2ME clients
 client_older_than=Update to clients older than version
-
+smpp_gw=SMPP gateway
 
 ####
 ## SMS COMMAND LOCALIZATION 
 ####
-
+edit_command=Edit SMS command
+data_element_category_combination=Data Element Category Combination
 sms_command_validation_alert=Fix validation problems before you save
+command_management=Command management
+code=Code
 name=Name 
 dataset=Dataset
 selected_dataset=Selected dataset
 code_value_separator=Code and value Separator
 no_codes_message=Reply message if no codes are sent (only the command):
+validation_error_space=*White space not allowed
+

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/struts.xml	2012-08-22 07:08:08 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/struts.xml	2012-08-30 12:47:05 +0000
@@ -142,6 +142,11 @@
       <param name="onExceptionReturn">plainTextError</param>
     </action>
 	
+    <action name="updateSMPPConfig" class="org.hisp.dhis.mobile.action.UpdateSMPPGateWayConfigAction">
+      <result name="success" type="velocity-json">../dhis-web-commons/ajax/jsonResponseSuccess.vm</result>
+      <param name="onExceptionReturn">plainTextError</param>
+    </action>
+  
     <action name="saveModemConfig" class="org.hisp.dhis.mobile.action.UpdateModemGateWayConfigAction">
       <result name="success" type="velocity-json">../dhis-web-commons/ajax/jsonResponseSuccess.vm</result>
       <param name="onExceptionReturn">plainTextError</param>

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/javascript/gateway.js'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/javascript/gateway.js	2012-08-22 07:08:08 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/javascript/gateway.js	2012-08-30 12:47:05 +0000
@@ -9,6 +9,8 @@
     	showById( "bulksmsFields" );
     } else if ( value == 'clickatell' ) {
     	showById( "clickatellFields" );
+    } else if ( value == "smpp_gw"){
+    	showById( "smppFields" );
     } else {
 	    showById( "genericHTTPFields" );
 	}
@@ -19,8 +21,10 @@
 {
 	 hideById( "modemFields" );
 	 hideById( "bulksmsFields" );
+	 hideById( "smppFields" );
 	 hideById( "clickatellFields" );
 	 hideById( "genericHTTPFields" );
+	 
 }
 
 function getValidationRulesGateway()
@@ -44,6 +48,12 @@
 			'bulksmsFields input[id=username]' : { 'required' : true },
 			'bulksmsFields input[id=password]' : { 'required' : true }
 		};
+	} else if ( currentType == 'smpp_gw' ) {
+		rules = {
+			'bulksmsFields input[id=name]' : { 'required' : true },
+			'bulksmsFields input[id=username]' : { 'required' : true },
+			'bulksmsFields input[id=password]' : { 'required' : true }
+		};
 	} else if ( currentType == 'clickatell' ) {
 		rules = {
 			'clickatellFields input[id=name]' : { 'required' : true },
@@ -127,6 +137,30 @@
 			} );
 		}
 	}
+	else if ( currentType == 'smpp_gw' )
+	{
+		var username = getFieldValue( 'smppFields input[id=username]' );
+		var password = getFieldValue( 'smppFields input[id=password]' );
+		if ( username == "" || password == "")
+		{	
+			showErrorMessage( i18n_required_data_error );
+		}
+		else
+		{
+			lockScreen();
+			jQuery.postJSON( "updateSMPPConfig.action", {
+				gatewayType: getFieldValue( 'gatewayType' ),
+				name: getFieldValue( 'smppFields input[id=name]' ),
+				username: getFieldValue( 'smppFields input[id=username]' ),
+				password: getFieldValue( 'smppFields input[id=password]' ),
+				port: getFieldValue( 'smppFields input[id=port]' ),
+				address: getFieldValue( 'smppFields input[id=address]' ),
+			}, function ( json ) {
+				unLockScreen();
+				showMessage( json );
+			} );
+		}
+	}
 	else if ( currentType == 'clickatell' )
 	{
 		lockScreen();

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/edit-sms-command.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/edit-sms-command.vm	2012-08-24 12:14:49 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/edit-sms-command.vm	2012-08-30 12:47:05 +0000
@@ -1,7 +1,7 @@
+#parse("/dhis-web-maintenance-mobile/smscommand/validate_javascript.vm")
+
 <script langauge="Javascript">
 
-    var VALIDATION_ERRORS = 0;
-
     function prepSubmit(){
     
       if(VALIDATION_ERRORS > 0){
@@ -22,41 +22,13 @@
       $("#updateSMSCommand").submit(); 
 
     }
-    
-    function validate(obj){
-        var validationErrorId = "#" + $(obj).attr("name") + "-validation-error";
-        validationErrorId = validationErrorId.replace(/\./g,'\\\.');
-        if(obj.value != null && obj.value.indexOf(" ") > -1){
-          if(!$(validationErrorId).length>0){
-            $(obj).after("<span id='" + $(obj).attr("name") + "-validation-error' style='color:red'>* whitespace not allowed</span>");
-            VALIDATION_ERRORS++;
-          }
-        }else{
-          if($(validationErrorId).length>0){
-            $(validationErrorId).remove();
-            VALIDATION_ERRORS--;
-          }
-        }
-    }
-    
-    $(document).ready(function() {   
-        $(".validate").each(function(){
-            validate(this);
-        });
-        $(".validate").change(function() {
-            validate(this);
-        });
-    });
+  
     
 </script>
 
-
-<div>
-    </div>
-<h3>Edit command</h3>
+<h3>$i18n.getString( "edit_command" )</h3>
 
 <form id="updateSMSCommand" name="updateSMSCommand" action="saveEditSMSCommandForm.action" method="post">
-
 	<table>
 	<thead>
       <tr>
@@ -68,7 +40,6 @@
 				<input type="hidden" value="$selectedCommandID" name="selectedCommandID" />
 			</td>
 		</tr>
-		
 		<tr>
 			<td>$i18n.getString( "name" )</td>
 			<td><input type="text" name="name" id="name" value="$SMSCommand.name" style="width:20em" class="validate" /></td>
@@ -78,13 +49,17 @@
 		  <td>$i18n.getString( "dataset" )</td>
 		  <td>#if($SMSCommand.dataset.name) $SMSCommand.dataset.name #end</td>
 		<tr>
+		<tr>
+          <td>$i18n.getString( "parser" )</td>
+          <td>#if($SMSCommand.parserType) $SMSCommand.parserType #end</td>
+        <tr>
 			<td>$i18n.getString( "code_value_separator" )</td>
 			<td>
 				<input type="text"  #if($SMSCommand.separator) value="$SMSCommand.separator" #end name="separator" style="width:20em" class="validate" />
 			</td>
 		</tr> 
-        <tr>
-            <td>$i18n.getString( "no_codes_message" )</td>
+        <tr >
+            <td style="width:150px">$i18n.getString( "no_codes_message" )</td>
             <td><textarea cols="35" type="text" name="defaultMessage">#if($SMSCommand.defaultMessage)$SMSCommand.defaultMessage#end</textarea></td>
         </tr>	
 	</table>
@@ -99,8 +74,8 @@
     <col style="width: 450px"/>
     <thead>
       <tr>
-        <th>Data Element Category Combination</th>
-		<th>Code</th>
+        <th>$i18n.getString( "data_element_category_combination")</th>
+		<th>$i18n.getString( "code" )</th>
       </tr>
     </thead>
          #foreach( $dataElement in $dataSetElements)
@@ -124,9 +99,10 @@
             #end  
          #end
     </table>
-	<br/>
-	
+    
+
+	<br/>	
     <input type="hidden" name="codeDataelementOption" id="codeDataelementOption" />
     <input  type="button" style="width: 100px" onclick="prepSubmit()" value="$i18n.getString( "save" )" />
-	
+    <input type="button" id ="btnBack" name ="btnBack" value="Back" style="width:8em" onclick="window.location.href='SMSCommands.action'"/>
 </form>
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/new-sms-command.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/new-sms-command.vm	2012-08-24 12:26:05 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/new-sms-command.vm	2012-08-30 12:47:05 +0000
@@ -1,3 +1,4 @@
+#parse("/dhis-web-maintenance-mobile/smscommand/validate_javascript.vm")
 
 <h3>Add command</h3>
 <form id="newSMSCommand" name="updateSMSCommand" action="createSMSCommandForm.action" method="post">
@@ -12,42 +13,43 @@
     </thead>
 		<tr>
 			<td>
-				Name (command word):
-			</td>
-			<td>
-				<input type="text" value="" id="name" name="name" style="width:20em"/>
-			</td>
-		</tr>
-<!--
-		<tr>
-			<td>
-			Parser:
-			</td>
-		<td>
-				<select name="parser" style="min-width:20em; margin:0;">
-					<option value="syntax1">Syntax1</option>
-					<option value="syntax2">Syntax2</option>
-				</select> 
-			</td>
--->
-		</tr>
-		<tr>
-			<td>
-			Dataset:
+				$i18n.getString( "name" )
+			</td>
+			<td>
+				<input type="text" value="" id="name" name="name" style="width:20em" class="validate"/>
+			</td>
+		</tr>
+		      <tr>
+		      <td>
+		      $i18n.getString( "parser" )
+		      </td>
+            <td>
+	   <select name="parserType" >
+                #foreach( $x in $parserType )
+                    <option value="$x">$x</option>
+                #end
+        </select> 	  
+                    </td>
+        </tr>
+		</tr>
+		<tr>
+			<td>
+			$i18n.getString( "dataset" )
 			</td>
 			<td>
 				<select name="selectedDataSetID" >
-					#foreach( $dataSet in $dataSets )
-				<option value="$dataSet.id" #if ($SMSCommand.dataset.id == $dataSet.id) selected #end >$dataSet.name</option>
-					#end
+				#foreach( $dataSet in $dataSets )
+			        <option value="$dataSet.id" #if ($SMSCommand.dataset.id == $dataSet.id) selected #end >$dataSet.name</option>
+				#end
 				</select> 
 			</td>
 		</tr>
-		
 		<tr>
-			<td><input id="save" type="submit" value="Submit" /></td>
+			<td colspan="2">
+			     <input id="save" type="submit"  style="width: 100px" value="$i18n.getString( "save" )" />
+			     <input type="button" id ="btnBack" name ="btnBack" value="Back" style="width:8em" onclick="window.location.href='SMSCommands.action'"/>
+			</td>
 		</tr>
-		
 	</table>
-	
+
 </form>
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/sms-commands.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/sms-commands.vm	2012-08-20 13:46:56 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/sms-commands.vm	2012-08-30 12:47:05 +0000
@@ -1,11 +1,9 @@
 <script type="text/javascript">
 	jQuery(document).ready(function(){	
-		
 		leftBar.showAnimated();
 	});
-
 </script>
-<h3>Command management</h3>
+<h3>$i18n.getString( "command_management" )</h3>
 <table class="mainPageTable">
 <tr>
 	<td style="vertical-align:top">
@@ -16,34 +14,24 @@
 			</td>
 		</tr>
 	</table>
-	
 	<table class="listTable" id="listTable">
-		
-          <thead>
-		  
+      <thead>
+      <tr>
+        <th>Name</th>
+        <th>Edit</th>
+		<th>Delete</th>
+      </tr>
+      </thead>
+	  <tbody id="list">
+    	 #foreach( $command in $SMSCommands )
           <tr>
-            <th>Name</th>
-            <th>Edit</th>
-			<th>Delete</th>
-          </tr>
-          </thead>
-		  <tbody id="list">
-	 #foreach( $command in $SMSCommands )
-      <tr>
-		<td height="35">$command.name </td>
-		<td><a href="editSMSCommand.action?selectedCommandID=$command.id">Edit</a></td>
-		<td><a href="deleteSMSCommand.action?deleteCommandId=$command.id">Delete</a></td>
-	  </tr><br/>
-    #end
-	
-	 </tbody>
-    
- 
+    		<td height="35">$command.name </td>
+    		<td><a href="editSMSCommand.action?selectedCommandID=$command.id">Edit</a></td>
+    		<td><a href="deleteSMSCommand.action?deleteCommandId=$command.id">Delete</a></td>
+    	  </tr>
+        #end
+	 </tbody> 
 </table>
 </td>
 </tr>
-</table>
-
-
-
-<p></p>
+</table>
\ No newline at end of file

=== added file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/validate_javascript.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/validate_javascript.vm	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/validate_javascript.vm	2012-08-30 12:47:05 +0000
@@ -0,0 +1,31 @@
+
+<script type="text/javascript">
+
+    var VALIDATION_ERRORS = 0;
+    
+    function validate(obj){
+        var validationErrorId = "#" + $(obj).attr("name") + "-validation-error";
+        validationErrorId = validationErrorId.replace(/\./g,'\\\.');
+        if(obj.value != null && obj.value.indexOf(" ") > -1){
+          if(!$(validationErrorId).length>0){
+            $(obj).after("<span id='" + $(obj).attr("name") + "-validation-error' style='color:red'>$i18n.getString( "validation_error_space" )</span>");
+            VALIDATION_ERRORS++;
+          }
+        }else{
+          if($(validationErrorId).length>0){
+            $(validationErrorId).remove();
+            VALIDATION_ERRORS--;
+          }
+        }
+    }
+    
+    $(document).ready(function() {   
+        $(".validate").each(function(){
+            validate(this);
+        });
+        $(".validate").change(function() {
+            validate(this);
+        });
+    });
+    
+</script>

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/updateGateway.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/updateGateway.vm	2012-08-22 07:08:08 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/updateGateway.vm	2012-08-30 12:47:05 +0000
@@ -26,13 +26,37 @@
 					<option value="bulksms" #if ( $!index == $!bulkIndex ) selected='selected' #end>$i18n.getString( "bulk_gw" )</option>
 					<option value="clickatell" #if ( $!index == $!clickatellIndex ) selected='selected' #end>$i18n.getString( "clickatell_gw" )</option>
 					<option value="http" #if ( $!index == $!httpIndex ) selected='selected' #end>$i18n.getString( "generic_http_gw" )</option>
-					<option value="modem" #if ( $!index == $!modemIndex ) selected='selected' #end>$i18n.getString( "modem_gw" )</option>					
+					<option value="modem" #if ( $!index == $!modemIndex ) selected='selected' #end>$i18n.getString( "modem_gw" )</option>
+					<option value="smpp_gw" #if ( $!index == $!smppIndex ) selected='selected' #end>$i18n.getString( "smpp_gw" )</option>					
 				</select>
 			</td>
 		</tr>
 		<tr>
 			<th colspan="2">$i18n.getString( "gateway_configuration" )</th>
 		</tr>
+		  #set( $smppGateway = $!gatewayConfigMap.get( $smppIndex ) )
+        <tbody id="smppFields">
+            <tr>
+                <td>$i18n.getString( "gateway_name" ):</td>
+                <td><input type="text" name="name" id="name" style="width: 28em" value="$!encoder.htmlEncode( $!smppGateway.name )"/></td>
+            </tr>
+            <tr>
+                <td>$i18n.getString( "username" ) <em title="$i18n.getString( 'required' )" class="required">*</em>:</td>
+                <td><input type="text" name="username" id="username" style="width: 28em" value="$!smppGateway.username"/></td>
+            </tr> 
+            <tr>
+                <td>$i18n.getString( "password" ) <em title="$i18n.getString( 'required' )" class="required">*</em>:</td>
+                <td><input type="text" name="password" id="password" style="width: 28em" value="$!smppGateway.password"/></td>
+            </tr>
+            <tr>
+                <td>$i18n.getString( "address" ) <em title="$i18n.getString( 'required' )" class="required">*</em>:</td>
+                <td><input type="text" name="address" id="address" style="width: 28em" value="$!smppGateway.address"/></td>
+            </tr>
+            <tr>
+                <td>$i18n.getString( "port" ) <em title="$i18n.getString( 'required' )" class="required">*</em>:</td>
+                <td><input type="text" name="port" id="port" style="width: 28em" value="$!smppGateway.port"/></td>
+            </tr>
+        </tbody>
 		#set( $bulkGateway = $!gatewayConfigMap.get( $bulkIndex ) )
 		<tbody id="bulksmsFields">
 			<tr>

=== modified file 'dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/action/MenuAction.java'
--- dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/action/MenuAction.java	2012-06-18 06:14:19 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/action/MenuAction.java	2012-08-30 12:47:05 +0000
@@ -161,7 +161,6 @@
             dataSet = dataSetService.getDataSet( dataSetId );
         }
 
-        unreadMessageConversationCount = messageService.getUnreadMessageConversationCount();
 
         return SUCCESS;
     }

=== removed file 'dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/IParser.java'
--- dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/IParser.java	2012-08-22 06:31:11 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/IParser.java	1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.hisp.dhis.sms.input;
-
-import java.util.Map;
-
-/**
- *
- * @author Christian
- */
-public interface IParser {
-    
-    static final String DATA_ENTRY_KEYWORD = "DHISDATAENTRYKEYWORD";
-    
-    public Map<String, String> parse(String sms);
-    
-    public void setSeparator(String separator);
-    
-}

=== modified file 'dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSInput.java'
--- dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSInput.java	2012-08-22 06:31:11 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSInput.java	2012-08-30 12:47:05 +0000
@@ -1,30 +1,16 @@
 package org.hisp.dhis.sms.input;
 
 import java.text.ParseException;
-import java.util.Map;
 
-import org.apache.commons.lang.StringUtils;
 import org.exolab.castor.types.Date;
-import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
-import org.hisp.dhis.dataelement.DataElementCategoryService;
-import org.hisp.dhis.datavalue.DataValue;
-import org.hisp.dhis.datavalue.DataValueService;
-import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.period.CalendarPeriodType;
-import org.hisp.dhis.period.Period;
 import org.hisp.dhis.sms.incoming.IncomingSms;
 import org.hisp.dhis.sms.incoming.IncomingSmsStore;
 import org.hisp.dhis.sms.incoming.SmsMessageEncoding;
 import org.hisp.dhis.sms.incoming.SmsMessageStatus;
 import org.hisp.dhis.sms.outbound.OutboundSms;
 import org.hisp.dhis.sms.outbound.OutboundSmsService;
-import org.hisp.dhis.smscommand.SMSCode;
-import org.hisp.dhis.smscommand.SMSCommand;
-import org.hisp.dhis.smscommand.SMSCommandService;
-import org.hisp.dhis.user.CurrentUserService;
-import org.hisp.dhis.user.User;
-import org.hisp.dhis.user.UserService;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.hisp.dhis.sms.parse.ParserManager;
+import org.hisp.dhis.sms.parse.SMSParserException;
 
 import com.opensymphony.xwork2.Action;
 
@@ -36,6 +22,8 @@
     implements Action
 {
 
+    private ParserManager smsParserManager;
+
     private String msisdn, sender, message, dca, reffering_batch, network_id, concat_reference, concat_num_segments,
         concat_seq_num, received_time;
 
@@ -47,18 +35,6 @@
 
     private IncomingSmsStore smsStore;
 
-    // Services
-    private CurrentUserService currentUserService;
-
-    private DataValueService dataValueService;
-
-    private UserService userService;
-
-    private SMSCommandService smsCommandService;
-
-    @Autowired
-    private DataElementCategoryService dataElementCategoryService;
-
     private OutboundSmsService outboundSmsService;
 
     public void setOutboundSmsService( OutboundSmsService outboundSmsService )
@@ -74,6 +50,7 @@
     public String execute()
         throws Exception
     {
+
         System.out.println( "Sender: " + sender + ", Message: " + message );
         IncomingSms sms = new IncomingSms();
         sms.setText( message );
@@ -101,124 +78,17 @@
 
         smsStore.save( sms );
 
-        OrganisationUnit orgunit = null;
-        for ( User user : userService.getUsersByPhoneNumber( sender ) )
-        {
-            OrganisationUnit ou = user.getOrganisationUnit();
-
-            // Might be undefined if the user has more than one org.units
-            // "attached"
-            if ( orgunit == null )
-            {
-                orgunit = ou;
-            }
-            else if ( orgunit.getId() == ou.getId() )
-            {
-                // same orgunit, no problem...
-            }
-            else
-            {
-                sendSMS( "User is associated with more than one orgunit. Please contact your supervisor." );
-                return ERROR;
-            }
-        }
-
-        if ( orgunit == null )
-        {
-            sendSMS( "No user associated with this phone number. Please contact your supervisor." );
-            return ERROR;
-        }
-
-        String[] marr = message.trim().split( " " );
-        if ( marr.length < 1 )
-        {
-            sendSMS("No marr");
-            return ERROR;
-        }
-        String commandString = marr[0];
-
-        boolean foundCommand = false;
-        for ( SMSCommand command : smsCommandService.getSMSCommands() )
-        {
-            if ( command.getName().equalsIgnoreCase( commandString ) )
-            {
-                foundCommand = true;
-                // Insert message type handler later :)
-                IParser p = new SMSParserKeyValue();
-                if ( !StringUtils.isBlank( command.getSeparator() ) )
-                {
-                    p.setSeparator( command.getSeparator() );
-                }
-
-                Map<String, String> parsedMessage = p.parse( message );
-                if ( parsedMessage.isEmpty() )
-                {
-                    sendSMS( command.getDefaultMessage() );
-                    return ERROR;
-                }
-                for ( SMSCode code : command.getCodes() )
-                {
-
-                    String upperCaseCode = code.getCode().toUpperCase();
-                    if ( parsedMessage.containsKey( upperCaseCode ) ) // Or fail
-                                                                      // hard???
-                    {
-
-                        String storedBy = currentUserService.getCurrentUsername();
-
-                        if ( StringUtils.isBlank( storedBy ) )
-                        {
-                            storedBy = "[unknown] from [" + sender + "]";
-                        }
-
-                        DataElementCategoryOptionCombo optionCombo = null;
-                        optionCombo = dataElementCategoryService.getDataElementCategoryOptionCombo( code.getOptionId() );
-
-                        Period period = code.getDataElement().getPeriodType().createPeriod();
-                        CalendarPeriodType cpt = (CalendarPeriodType) period.getPeriodType();
-                        period = cpt.getPreviousPeriod( period );
-
-                        DataValue dv = dataValueService.getDataValue( orgunit, code.getDataElement(), period,
-                            optionCombo );
-
-                        if ( dv == null )
-                        {
-                            // New data element
-                            DataValue dataVal = new DataValue();
-
-                            dataVal.setOptionCombo( optionCombo );
-
-                            dataVal.setSource( orgunit );
-                            dataVal.setDataElement( code.getDataElement() );
-
-                            dataVal.setPeriod( period );
-                            dataVal.setComment( "" );
-                            dataVal.setTimestamp( new java.util.Date() );
-                            dataVal.setStoredBy( storedBy );
-                            dataVal.setValue( parsedMessage.get( upperCaseCode ) );
-                            dataValueService.addDataValue( dataVal );
-                        }
-                        else
-                        {
-                            // Update data element
-                            dv.setValue( parsedMessage.get( upperCaseCode ) );
-                            dv.setOptionCombo( optionCombo );
-                            dataValueService.updateDataValue( dv );
-                        }
-                    }
-                }
-            }
-        }
-        if ( foundCommand )
-        {
-            sendSMS( "SMS successfully received" );
-        }
-        else
-        {
-            sendSMS( "Command '" + commandString + "' does not exist" );
-            return ERROR;
-        }
-
+        try
+        {
+            smsParserManager.parse( sender, message );
+        }
+        catch ( SMSParserException e )
+        {
+            sendSMS( e.getMessage() );
+            return ERROR;
+        }
+
+        sendSMS( "SMS successfully received" );
         // TODO DataEntry stuff
         return SUCCESS;
     }
@@ -236,37 +106,12 @@
         }
     }
 
-    public void setDataElementCategoryService( DataElementCategoryService dataElementCategoryService )
-    {
-        this.dataElementCategoryService = dataElementCategoryService;
-    }
-
-    public void setSmsCommandService( SMSCommandService smsCommandService )
-    {
-        this.smsCommandService = smsCommandService;
-    }
-
-    public void setCurrentUserService( CurrentUserService currentUserService )
-    {
-        this.currentUserService = currentUserService;
-    }
-
-    public void setDataValueService( DataValueService dataValueService )
-    {
-        this.dataValueService = dataValueService;
-    }
-
     public void setSmsStore( IncomingSmsStore smsStore )
     {
         System.out.println( "Setting SMSStore: " + smsStore );
         this.smsStore = smsStore;
     }
 
-    public void setUserService( UserService userService )
-    {
-        this.userService = userService;
-    }
-
     public String getConcat_num_segments()
     {
         return concat_num_segments;
@@ -397,4 +242,9 @@
         this.source_id = source_id;
     }
 
+    public void setSmsParserManager( ParserManager smsParserManager )
+    {
+        this.smsParserManager = smsParserManager;
+    }
+
 }

=== removed file 'dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSParserKeyValue.java'
--- dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSParserKeyValue.java	2012-08-20 15:02:29 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/input/SMSParserKeyValue.java	1970-01-01 00:00:00 +0000
@@ -1,50 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.hisp.dhis.sms.input;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @author Magnus Korvald
- */
-public class SMSParserKeyValue
-    implements IParser
-{
-
-    private String defaultPattern = "([a-zA-Z]+)\\s*(\\d+)";
-
-    private Pattern pattern = Pattern.compile( defaultPattern );
-
-    @Override
-    public Map<String, String> parse( String sms )
-    {
-
-        HashMap<String, String> output = new HashMap<String, String>();
-
-        Matcher m = pattern.matcher( sms );
-        while ( m.find() )
-        {
-            String key = m.group( 1 );
-            String value = m.group( 2 );
-            System.out.println( "Key: " + key + " Value: " + value );
-            if ( key != null && value != null )
-            {
-                output.put( key.toUpperCase(), value );
-            }
-        }
-
-        return output;
-    }
-
-    public void setSeparator( String separator )
-    {
-        String x = "(\\w+)\\s*" + separator.trim()  + "\\s*(\\d+)";
-        pattern = Pattern.compile( x );
-    }
-
-}

=== modified file 'dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml	2012-08-22 06:31:11 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml	2012-08-30 12:47:05 +0000
@@ -6,10 +6,7 @@
 	
     <bean id="org.hisp.dhis.sms.input.SMSInput" class="org.hisp.dhis.sms.input.SMSInput">
         <property name="smsStore" ref="org.hisp.dhis.sms.incoming.IncomingSmsStore"/>
-        <property name="userService" ref="org.hisp.dhis.user.UserService"/>
-        <property name="smsCommandService" ref="smsCommandService" />
-        <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService"/>
-        <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService"/>
+        <property name="smsParserManager" ref="org.hisp.dhis.sms.parse.DefaultParserManager" />
     </bean>