Package com.funambol.syncclient.blackberry

Source Code of com.funambol.syncclient.blackberry.SyncClient$ConfigurationScreen

/*
* Funambol is a mobile platform developed by Funambol, Inc.
* Copyright (C) 2003 - 2007 Funambol, Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*
* You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
* 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by Funambol" logo. If the display of the logo is not reasonably
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by Funambol".
*/
package com.funambol.syncclient.blackberry;

import java.util.Hashtable;

import net.rim.blackberry.api.pdap.BlackBerryPIMList;

import javax.microedition.pim.PIM;

import com.funambol.syncclient.blackberry.email.impl.Constants;
import com.funambol.syncclient.blackberry.email.impl.Poller;
import com.funambol.syncclient.blackberry.listener.SMSListener;
import com.funambol.syncclient.blackberry.listener.Sync4jContactListener;
import com.funambol.syncclient.blackberry.listener.Sync4jEventListener;
import com.funambol.syncclient.spds.SyncManagerFactory;
import com.funambol.syncclient.sps.ContactDataStore;
import com.funambol.syncclient.sps.DataAccessException;
import com.funambol.syncclient.sps.DataStore;
import com.funambol.syncclient.sps.EventDataStore;
import com.funambol.syncclient.sps.MailDataStore;
import com.funambol.syncclient.util.Log;
import com.funambol.syncclient.util.StaticDataHelper;

import net.rim.device.api.servicebook.ServiceBook;
import net.rim.device.api.servicebook.ServiceRecord;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.PersistentObject;
import net.rim.device.api.system.PersistentStore;
import net.rim.device.api.system.RadioInfo;
import net.rim.device.api.system.TrackwheelListener;

import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;

import net.rim.device.api.ui.component.BasicEditField;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.CheckboxField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.DialogClosedListener;
import net.rim.device.api.ui.component.EditField;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.NumericChoiceField;
import net.rim.device.api.ui.component.ObjectChoiceField;
import net.rim.device.api.ui.component.PasswordEditField;
import net.rim.device.api.ui.container.PopupScreen;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.component.Status;


import net.rim.blackberry.api.mail.event.FolderEvent;
import net.rim.blackberry.api.mail.event.FolderListener;

import net.rim.blackberry.api.mail.SendListener;
import net.rim.blackberry.api.mail.FolderNotFoundException;
import net.rim.blackberry.api.mail.Folder;
import net.rim.blackberry.api.mail.Message;
import net.rim.blackberry.api.mail.NoSuchServiceException;
import net.rim.blackberry.api.mail.Session;
import net.rim.blackberry.api.mail.Store;

import net.rim.blackberry.api.phone.Phone;

//import funambol.syncclient.blackberry.listener.CallsListener;


import net.rim.device.api.system.Memory;

/**
* Provides the user interface with the configuration
* settings, mail synchronization capabilities (polling
* included), and contacts and calendar events synchronization
*
*/
public class SyncClient extends UiApplication implements Runnable,
                                                         FolderListener {
                                                            
    final private static String PROP_SERVER_URL         = "serverUrl";
    final private static String PROP_LOGIN              = "login";
    final private static String PROP_GATEWAYAPN         = "gatewayApn";
    final private static String PROP_GATEWAYIP          = "gatewayIp";
    final private static String PROP_GATEWAYPORT        = "gatewayPort";

    final private static String ERROR_NOT_AUTHORIZED    = "401";
    final private static String ERROR_NOT_FOUND         = "404";
    final private static String ERROR_SERVER            = "511";
    final private static String ERROR_REFRESH_REQUIRED  = "508";
    final private static String IMAGE_LOGO              = "logo_middle.png";

    final private static String CONTACT_SOURCE_TYPE     = "text/x-s4j-sifc";
    final private static String CONTACT_SOURCE_NAME     = "xcard";
    final private static String CALENDAR_SOURCE_TYPE    = "text/x-s4j-sife";
    final private static String CALENDAR_SOURCE_NAME    = "xcal";
    final private static String MAIL_SOURCE_NAME        = "mail";
    final private static String MAIL_SOURCE_TYPE        = "application/vnd.omads-email+xml";
    
    public static final String VER = "1.4.10";//only for logging purposes (TODO: retrieve version from the .alx file)
    public static long CONFIG_KEY = 0xbc565a75eda532eL;

    // Used to select which source to sync in synchronize()
    public static final int SYNC_CONTACTS = 0x0001;
    public static final int SYNC_CALENDAR = 0x0002;
    public static final int SYNC_MAIL     = 0x0004;

    private Thread                thread = null;
    private AppScreen             appScreen = null;
    private RichTextField         statusField = null;
    private BlackBerryPIMList     listContact = null;
    private BlackBerryPIMList     listEvent = null;
   
    //private CallsListener         listenerCalls = null;
    private Sync4jContactListener listenerContact = null;
    private Sync4jEventListener   listenerEvent = null;
   
    private Thread                mailEventHandler = null;
    private Thread                tcpEventHandler = null;
    private Thread                radioEventHandler = null;

    private Hashtable             properties = null;

    private StaticDataHelper      sdh = null;

    private String                contactSourceType = null;
    private String                contactSourceName = null;

    private String                calendarSourceType = null;
    private String                calendarSourceName = null;
    private String                mailSourceType = null;
    private String                mailSourceName = null;   
    private SMSListener           listenerSMS = null;
    private Thread                pollerThread = null;
    private Thread                smsThread = null;
    public static boolean         inSynchronize = false;
   
    //persistent object to store the configuration
    private static PersistentObject store;
   
    /**
     * The persistent object to store the
     * polling and sms in-sync flag
     */
    private static PersistentObject syncStore;//storePoller
   
    private Poller poller = null;
   
    private boolean pollerEnabled = false;
    private boolean newVersion = false;//it gets true if OS device is 4.1 onwards
    private boolean showServiceWarning = false;//false: Message Services are activated
    private boolean mailSyncAllowed = false;//false: don't display per default the mail settings
   
   
    static {
        store = PersistentStore.getPersistentObject(CONFIG_KEY);
    }

    /**
     * The default constructor. It opens internally the BlackBerry
     * PIM lists (contacts and calendar events), adds a listener to
     * them and to the mail folders, and pushes the home screen to
     * allow user configuration
     */
    public SyncClient() throws Exception {
       
        // DEBUG only (needed to activate log during conf load
        Log.setLevel(Log.TRACE);
       
        /*
         * get configurations contents from
         * the store. The class configuration
         * initializes also StaticDataHelper defaults.
         *
         * TODO: remove StaticDataHelper and the need to instatiate conf
         */
        Configuration conf = new Configuration(this.getClass());
        conf = null;
       
        Configuration.load();
       
        // Set the log level
        Log.setLevel(Configuration.logLevel);
       
        // Init the class member to access StaticDataHelper
        sdh = new StaticDataHelper();
       
        newVersion = checkOSVersion();

        //a list of contacts from the device's store
        listContact = (BlackBerryPIMList)
                            PIM.getInstance().
                                openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE);//returns a PIMList object,
                                                                              //but on the Berry this is
                                                                              //a BlackBerryPIMList object
       
        //a list of calendar events from the device's store
        listEvent = (BlackBerryPIMList)
                            PIM.getInstance().
                                openPIMList(PIM.EVENT_LIST, PIM.READ_WRITE);

        listenerContact = new Sync4jContactListener();
        listenerEvent = new Sync4jEventListener();
        //listenerCalls = new CallsListener();//this is to listen to incoming calls to alert the client
       
        /*
        listenerSMS = new SMSListener();
        */
       
        //DEBUG INFO
        Session session = Session.getDefaultInstance();
        StaticDataHelper.log("### in SyncClient(): session is " + session +
                             ", mailSyncAllowed is " + mailSyncAllowed +
                             ", showServiceWarning is " + showServiceWarning);

        //Phone.addPhoneListener(listenerCalls);//a listener to the incoming calls
                                              //is added to the system (experimental)

        listContact.addListener(listenerContact);//to the contacts list a Funambol
                                                 //contacts listener is added
                                                
        listEvent.addListener(listenerEvent);//to the calendar events list a Funambol
                                             //calendar listener is added
        
        try {
           
            /*
             * 'this' class (remember, it implements the FolderListener
             * interface) is added to the device's store as a
             * listener to the changes that may occurr in the mail
             * folders (the mail folders are part of the device's store)
             */
            setMailListener();
                             
            StaticDataHelper.log(">>>>>> In SyncClient() try block: flag mailSyncAllowed is " + mailSyncAllowed);
            //mailSyncAllowed = true;//and showServiceWarnig is already false per default
            StaticDataHelper.log(">>>>>> In SyncClient() try block: flag mailSyncAllowed is " + mailSyncAllowed);
       
        } catch (NullPointerException npe) {//if the default Session in setMailListener() is null
                           
            StaticDataHelper.log(">>>>>> In SyncClient() catch block: flag mailSyncAllowed is " + mailSyncAllowed);
            StaticDataHelper.log(">>>>>> EMAIL SESSION NOT PRESENT! YOU CAN'T SYNC EMAIL!");
           
            /*
             * Due to this flag, just after the configuration main screen
             * is displayed, a warning is displayed too (see the last
             * instructions at the end of this constructor)
             */
            showServiceWarning = true;//true: Message Services aren't active! And mailSyncAllowed is false per default
        }
       
        // Check if no sync source defined (FIXME: shouldn't be in synchronize()?)
        if (!Configuration.syncContact &&
            !Configuration.syncCalendar &&
            !Configuration.syncMail) {
           
            displayStatus(sdh.getLanguage("nothing-sync-enable"));
        }
       
        if (Configuration.enablePolling) {
           
            Poller poller = new Poller();
            poller.setSyncClientObj(this);
           
            pollerThread = new Thread(poller);
            pollerThread.start();
           
        }
       
        // -------------------------------------------------------
        if (Configuration.enableSmsSync) {
           
            listenerSMS = new SMSListener();
           
            //to pass a SyncClient object to the SMSListener class
            listenerSMS.setSyncClientObj(this);
           
            smsThread = new Thread(listenerSMS);
            smsThread.start();
        }
        // -------------------------------------------------------
       
        /*
         * Building an AppScreen, a ConfigurationScreen
         * object is built as well
         */
        appScreen = new AppScreen();
       
        /*
         * The UI engine must be accessed holding
         * the event lock object shared with the
         * application's main thread, otherwise an
         * IllegalStateException is thrown (the
         * event lock is held here where the screen
         * is pushed in the foreground)
         */
        synchronized (getEventLock()) {
            pushScreen(appScreen);
        }
       
        /*
         * It is very important that this notification occurs only
         * after the application's main screen is displayed (see
         * just here above), otherwise it gets overlapped by the
         * main screen. Using the solution as in
         * showMessageServicesWarning() is the only way to display
         * a Dialog window in a different thread than the one running
         * the event dispatcher (otherwise an exception is thrown:
         * "pushModalScreen called by a non-event thread")
         */
        if (showServiceWarning) {
            showMessageServicesWarning();
        }
    }//end constructor
   
   
    /**
     * Creates a useful modal window to be used in every
     * context. See documentation at {@link http://tinyurl.com/bdyeh}
     *
     * @param message The message you want to incorporate
     *                in the modal window
     */
    private void alert(final String message) {
           
            UiApplication.getUiApplication().invokeLater(new Runnable() {
               
                public void run() {
               
                    Dialog.ask(Dialog.D_OK, message);
                   
                    //Calling invalidate() on your screen forces the paint
                    //method to be called.
                    //appScreen.invalidate();
                }
            });
        }
   
    public static void showMessageServicesWarning() {
        Dialog warning = new Dialog(Dialog.D_OK,
                                    "No message services configured. Please activate the BlackBerry Email service in order to sync mail messages too",
                                    1,
                                    Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION),
                                    Manager.LEAVE_BLANK_SPACE);
       
        synchronized(getEventLock()) {                               
            UiApplication.getUiApplication().pushScreen(warning);
        }
    }
    
    /**
     * Check the version of the device's operating system.
     * Some features of the application are available only
     * if the the OS version is 4.1 upwards
     *
     * @return true if the OS version of the device is 4.1 upwards
     */
    boolean checkOSVersion() {
        sdh.setOS();
        String version = sdh.getOS();
        StaticDataHelper.log(">>> Checking the OS version of the device: " + version);
        if (version.charAt(0) == '4' && version.charAt(2) >= '1') {
            return true;//the device's OS is 4.1 upwards
        }
       
        return false;//the device's OS is 4.0 downwards
    }

    /**
     * This method is the implementation of the sendMessage method from
     * interface SendListener.
     */
/*    public boolean sendMessage(Message msg) {
        try {
            StaticDataHelper.log("Persistent store: " + PersistentStore.getSynchObject());
            StaticDataHelper.log("Number of objects in storage: " + String.valueOf(Memory.getPersistentStats().getObjectCount()));

            msg.setStatus(Message.Status.TX_PENDING, 0);
            // Reset the draft flag in case it was a sent draft
            msg.setFlag(Message.Flag.SAVED_THEN_ORPHANED, false);

            //bug fix 1113
            if (inSynchronize) {
                StaticDataHelper.log("[INFO]sendMessages: another sync in progress...");
                // FIXME: what to say to the user? Wait for the sync to stop?
                return false;
            }

            new Thread() {
                public void run() {
                    inSynchronize = true;
                    try {
                        // Send the message
                        synchronizeMail();      // FIXME: synchronize(SYNC_MAIL)?
                        // Move it to SENT if successful
                        synchronizeMail();
                    }
                    //catch (Exception e) {
                    catch (Throwable e) {
                       
                        Log.error("[LOG]Exception in SyncClient.sendMessage: " + e.toString());
                       
                        alert(e.getMessage());
                       
                        // TODO: set the message status to TX_ERROR
                       
                    }
                    finally {
                        inSynchronize = false;
                    }
                }   
            }.start();  

        }
        finally {
           
             // FIXME: check if this statement
             // is reached before the thread
             // above is started
            
            setMailListener();
        }
        return false;
    }
  */     
    /**
     * Callback function for Email Message Added Event.
     * One of the only two methods provided in the RIM
     * interface {@link FolderListener}
     *
     * @param e
     */
    public void messagesAdded(FolderEvent e) {
       
        StaticDataHelper.log("[LOG]Entering messagesAdded(:FolderEvent)");
       
        final Message mailMessage = e.getMessage();
        StaticDataHelper.log("\n[MSG]Properties of this message:");
        MailDataStore.printMessageInfo(mailMessage);
       
        Folder folder = mailMessage.getFolder();
        int folderType = folder.getType();
        MailDataStore.printFolderInfo(folder);
       
        switch (mailMessage.getStatus()) {
            // If it's composing, it's a draft
            case Message.Status.TX_COMPOSING:           
                try {
                    mailMessage.setFlag(Message.Flag.SAVED_THEN_ORPHANED, true);
                }
                catch (Exception ex) {
                    StaticDataHelper.log("\n[ERROR]: Error saving message as draft: "+
                                         ex.toString() );
                }
                StaticDataHelper.log("[INFO]Message has been saved as draft.");
                break;
            case Message.Status.TX_ERROR:
                StaticDataHelper.log("[INFO]Message status: TX_ERROR");
                if(folderType == Folder.SENT){
                    // If the message is in status TX_ERROR, it is because the
                    // message was sent using sendMessage and blocked for RIM
                    // standard processing
                    mailMessage.setStatus(Message.Status.TX_PENDING, 0);
                    //mailMessage.updateUi();
                    StaticDataHelper.log("\n[DEBUG]: Folder type SENT. Message status set to SENDING....");
                }
                break;
            case Message.Status.TX_GENERAL_FAILURE:
                StaticDataHelper.log("[INFO]Message status: TX_GENERAL_FAILURE");
        }
    }
   
    /**
     * Callback function for Email Message Removed Event.
     * One of the only two methods provided in the RIM
     * interface {@link FolderListener}
     *
     * @param e
     */
    public void messagesRemoved(FolderEvent e) {
       
        StaticDataHelper.log("[LOG]Entering messagesRemoved(:FolderEvent)");
       
        try {
            sdh.loadLanguage(this.getClass());
            sdh.loadDefaultValue();
               
        } catch (Exception ioex) {
            System.out.println("Can't load language XML");
        }
       
        synchronized (this) {
            if (inSynchronize)
                return;
            inSynchronize = true;       
            removeMailListener();
            StaticDataHelper.log("Message Removed");
           
            Message mailMessage = e.getMessage();
            Folder folder = mailMessage.getFolder();
               
            try {   
                StaticDataHelper.log("[DELMAIL]Starting Message Processing Thread");
                String strFolder = null;
               
                if (mailMessage.isSet(Message.Flag.SAVED_THEN_ORPHANED)) {
                    strFolder = "D";
                } else {
                    if(folder.getFullName().indexOf("Outbox") >= 0) {
                        strFolder = "O";
                    }
                    else if (folder.getFullName().indexOf("Inbox") >= 0) {
                        strFolder = "I";
                    }
                }
               
                DataStore dataStore = DataStore.getDataStore(Configuration.mailSourceUri);
                dataStore.appendData(strFolder + ":" +
                                     new Integer(mailMessage.getMessageId()).toString(), Constants.DELETEDITEMS);
            } catch (Exception exp) {
                StaticDataHelper.log("[DELMAIL]Exception in SyncClient.messagesRemoved(:FolderEvent): " + exp.toString());
            } finally {
                setMailListener();       
                inSynchronize = false;
            }
        }
    }
   
    /**
        * Adds the folder listener
        */
    public void setMailListener() {
        Session session = Session.getDefaultInstance();//waitForDefaultInstance() used to
                                                        //retrieve this device's default
                                                        //mail service is blocking!
        Store store = session.getStore();
       
        //The listener is invoked when FolderEvents
        //occur on *any* folder in the store
        store.addFolderListener(this);
        //store.addSendListener(this);
    }
   
   
    /**
     *
     * Removes the folder listener
     */
    public void removeMailListener() {
        Store store = Session.getDefaultInstance().getStore();
        store.removeFolderListener(this);
        //store.removeSendListener(this);
    }
   
   
    public void synchronizeMail() throws Exception {//chnged from default to public
   
        mailSourceType  = MAIL_SOURCE_TYPE;
        mailSourceName  = MAIL_SOURCE_NAME;
       
        // FIXME:  why we need to re-load it?????
        Configuration.load();
       
       
        String login = Configuration.userName + ":" + Configuration.password;
                   
        /*
         * they are used in the sync initialization
         * phase: see the SyncManager sync() below
         */
        properties = new Hashtable();

        properties.put(PROP_SERVER_URL  ,  Configuration.syncUrl);
        properties.put(PROP_LOGIN       ,  login);
        //TODO customize for OS version
        properties.put(PROP_GATEWAYAPN  ,  Configuration.gatewayApn);
        properties.put(PROP_GATEWAYIP   ,  Configuration.gatewayIp);
        properties.put(PROP_GATEWAYPORT ,  Configuration.gatewayPort);
       
        sdh.setOS();//from the system infos!
       
        SyncManagerFactory.getSyncManager(Configuration.mailSourceUri,
                                          mailSourceType,
                                          mailSourceName,
                                          properties).sync();
    }//end synchronizeMail
   
   
    /**
     * Invoked when the synchronize button
     * in the menu of the home screen is clicked. In this
     * case a thread representing this runnable class
     * (SyncClient) is created and the run() method
     * implemented by SyncClient is fired.
     * <p>
     * In this case the 'syncMask' is always
     * {@code 0111} (also all ones, because the 0 on the
     * left is never used), because passed to this method
     * as a constant (result of a bit OR between
     * constants). A bit AND (&) with another
     * binary value is always different from 0 when
     * this value is also different from 0. Ergo the
     * goal of this method is to perform a sync on
     * all sources without distiction. Only
     * {@code synchronize(int)} gives you the possibility
     * to distinguish between different sources by
     * using a mask as a combination of unique binary
     * (or hex) values
     *
     * @param void
     * @return void
     * @see run()
     * @see SynchClient$AppScreen#syncMenu
     */
    public void synchronize() throws Exception {
        synchronize(SYNC_CONTACTS|SYNC_CALENDAR|SYNC_MAIL);
    }

    /**
     * This method starts a synchronization on the specified sources,
     * if they are also configured by the user. It is used both for
     * user and server initialized sync
     *
     * @param syncMask A bit mask of sources to sync
     */
    public void synchronize(int syncMask) throws Exception {
       
        StaticDataHelper.log("[LOG]Entering SyncClient.synchronize(:int). 'inSynchronize' is " + inSynchronize);
       
        try {
           
            //hard coded values in this class
            contactSourceType  = CONTACT_SOURCE_TYPE  ;//text/x-s4j-contact
            contactSourceName  = CONTACT_SOURCE_NAME  ;//xcard
            calendarSourceType = CALENDAR_SOURCE_TYPE ;//text/x-s4j-calendar
            calendarSourceName = CALENDAR_SOURCE_NAME ;//xcal
            mailSourceType     = MAIL_SOURCE_TYPE     ;//application/vnd.omads-email+xml
            mailSourceName     = MAIL_SOURCE_NAME     ;//mail

            if (!Configuration.syncContact &&
                !Configuration.syncCalendar &&
                !Configuration.syncMail) {
                   
                displayStatus(sdh.getLanguage("nothing-sync-enable"));
                //+ ":\n" + sdh.getLanguage("please-configure"));

                return;
            }

            /*
             * apply requested mask
             */
            final boolean syncContact  = Configuration.syncContact &&
                                         (syncMask & SYNC_CONTACTS) != 0;
            final boolean syncCalendar = Configuration.syncCalendar &&
                                         (syncMask & SYNC_CALENDAR) != 0;
            final boolean syncMail     = Configuration.syncMail &&
                                         (syncMask & SYNC_MAIL) != 0;

            sdh.setOS();
           
            String login = Configuration.userName + ":" + Configuration.password;
           
            properties = new Hashtable();

            properties.put(PROP_SERVER_URL  ,  Configuration.syncUrl);
            properties.put(PROP_LOGIN       ,  login        );
            //TODO customize for OS version
            properties.put(PROP_GATEWAYAPN  ,  Configuration.gatewayApn  );
            properties.put(PROP_GATEWAYIP   ,  Configuration.gatewayIp   );
            properties.put(PROP_GATEWAYPORT ,  Configuration.gatewayPort );

            boolean signal = true;

            if ((RadioInfo.getState() != RadioInfo.STATE_ON) ||
                (RadioInfo.getSignalLevel() == RadioInfo.LEVEL_NO_COVERAGE)) {
                signal = false;
            }

            if (!signal) {
                if (RadioInfo.getState() == RadioInfo.STATE_OFF) {
                    displayStatus(sdh.getLanguage("no_network_available"));
                } else {
                    displayStatus(sdh.getLanguage("no_network_available_later"));
                }
            }
           

            if (signal && (syncContact || syncCalendar || syncMail)) {
                  
                if (inSynchronize) {
                    // Notify the user that another sync is in progress
                    // TODO: use language.xml for the message
                    displayStatus("Synchronization in progress, try later");
                   
                    return;
                }               
                   
                inSynchronize = true;
                StaticDataHelper.log("[LOG]In SyncClient.synchronize(:int) 'inSynchronize' is " + inSynchronize);
               
                Thread syncThread = new Thread() {//SyncClient$2
               
                    public synchronized void run() {
                        // -- SYNCING CONTACTS --
                        if (syncContact) {
                            StaticDataHelper.log("@@@ Contacts: Trying to display the Please wait status...");
                            displayStatus(sdh.getLanguage("synch-contact-wait") + "\n" +                                                                                    
                                          sdh.getLanguage("please-wait"));
                                           
                            listContact.removeListener(listenerContact);
                               
                            try {
                                // --------------------------------------------------
                                SyncManagerFactory.getSyncManager(Configuration.contactSourceUri,
                                                                  contactSourceType,
                                                                  contactSourceName,
                                                                  properties).sync();  
                                // --------------------------------------------------
                                listContact.addListener(listenerContact);
                               
                            } catch (Exception e) {
                               
                                displayStatus(sdh.getLanguage("synch-failed") + " " +
                                              getSynchError(e.getMessage(),
                                              "address book",
                                              Configuration.contactSourceUri));
                                             
                                //bug fix 1113
                                inSynchronize = false;
                                return;
                       
                            } finally {
                                //bug fix 1113
                                if (!syncCalendar && !syncMail) {
                                    inSynchronize = false
                                }
                            }
                        }
                       
                        // -- SYNCING CALENDAR EVENTS --
                        if (syncCalendar) {
                           
                            StaticDataHelper.log("@@@ Calendar events: Trying to display the Please wait status...");
                            displayStatus(sdh.getLanguage("synch-calendar-wait") + "\n" +
                                            sdh.getLanguage("please-wait"));
                           
                            listEvent.removeListener(listenerEvent);

                            try {
                                // --------------------------------------------------
                                SyncManagerFactory.getSyncManager(Configuration.calendarSourceUri,
                                                                  calendarSourceType,
                                                                  calendarSourceName,
                                                                  properties).sync();
                                // --------------------------------------------------                                 
                               
                                listEvent.addListener(listenerEvent);

                            } catch (Exception e) {
                               
                                displayStatus(sdh.getLanguage("synch-failed") + " " +
                                                getSynchError(e.getMessage(),
                                                "calendar",
                                                Configuration.calendarSourceUri));
                                //bug fix 1113               
                                inSynchronize = false;
                                return;
                            } finally {
                                //bug fix 1113
                                if (!syncMail) {
                                    inSynchronize = false
                                }
                            }
                        }

                        // -- SYNCING EMAIL --
                        if (syncMail) {
                           
                            StaticDataHelper.log("@@@ Email: Trying to display the Please wait status...");
                            displayStatus(sdh.getLanguage("synch-mail-wait") + "\n" +     
                                            sdh.getLanguage("please-wait"));
                            try {
                                removeMailListener();
                               
                                // --------------------------------------------------
                                StaticDataHelper.log("[EMAIL]Performing the 1st sync in synchronize(:int)");                
                                SyncManagerFactory.getSyncManager(Configuration.mailSourceUri,
                                                                  mailSourceType,
                                                                  mailSourceName,
                                                                  properties).sync();
                                /* Only for sending
                                StaticDataHelper.log("[EMAIL]Performing the 2nd sync in synchronize(:int)");                                 
                                SyncManagerFactory.getSyncManager(mailSourceURI,
                                                                  mailSourceType,
                                                                  mailSourceName,
                                                                  properties).sync();
                                // -------------------------------------------------- */
                            }
                            //catch (Exception e) {
                            catch (Throwable e) {
                               
                                StaticDataHelper.log("<<<>>>Exception in SyncClient.synchronize(:int) --> "
                                                     + e.toString()
                                                     + ", syncing source: "
                                                     + Configuration.mailSourceUri);
                                                    
                                displayStatus(sdh.getLanguage("synch-failed") + " " +
                                                getSynchError(e.getMessage(),
                                                "mail",
                                                Configuration.mailSourceUri));
                                                    
                                /*
                                 * otherwise the error message is covered by
                                 * the message about the end of a successful
                                 * synchronization here below. The method is
                                 * exited, but first the 'finally' clause is
                                 * reached anyway and its content executed
                                 */
                                return;
                               
                            } finally {
                               
                                /*
                                 * bug fix 1113
                                 *
                                 * we don't need to clear the
                                 * flag already in the catch
                                 * clause because this is the
                                 * last type of synchronization
                                 * performed
                                 */
                                inSynchronize = false;
                               
                                setMailListener();
                            }
                        }
                       
                        // -- END OF A SUCCESSFUL SYNCHRONIZATION
                        displayStatus(sdh.getLanguage("synch-success"));                       
                    }//end run()               
                };//end constructor Thread()
               
                syncThread.start();
               
            }//end if
        } catch (Exception e) {
            displayStatus(sdh.getLanguage("synch-failed") +
                                          " " + e.getMessage());
            throw e;
           
        } finally {
           
            /*
             * bug fix 1113
             *
             * The statements in the 'finally'
             * block are executed immediately,
             * still before the synchronization
             * cycle contained in the syncThread
             * is started and ended
             */
            //inSynchronize = false;
        }
    }

    /**
     * This method is invoked to set/change the status message on the home screen.
     *
     * @param String: Message
     * @return void
     */
    void displayStatus(String message)
    {
        synchronized(getEventLock())
        {
            AppScreen as = null;

            statusField = new RichTextField("", Field.NON_FOCUSABLE) ;
            as          = new AppScreen()                            ;
            statusField.setText(message);
            as.setStatus(statusField);
            pushScreen(as);
        }
    }

    /**
     * Overridden run method of Runnable interface.
     * A seperate thread is created to synchronize data with sync server.
     *
     * 'thread' is always the same Thread object in this class, representing
     * the runnable class SyncClient itself. It is created by choosing the
     * Synchronize menu item
     *
     * @param void
     * @return void
     */
    public void run() {
        try {
            Thread current = Thread.currentThread();

            if (thread == current) {
                synchronized (this) {
                   synchronize();
                }
            }

        } catch (Exception ex) {
            StaticDataHelper.log(">>> Exception in SyncClient.run() --> " + ex.toString());
            displayStatus(sdh.getLanguage("exch-while-synch") + " " + ex);
        }
    }

    /**
     * return error message
     * @param error
     * @param remoteDBType
     * @param sourceUri
     */
    private String getSynchError(String error,
                                 String remoteDBType,
                                 String sourceUri) {
                                    
        if (ERROR_NOT_AUTHORIZED.equals(error)) {
            return sdh.getLanguage("not-authorized-user-and-password");
           
        } else if (ERROR_NOT_FOUND.equals(error)) {
            return sdh.getLanguage("not-found-remote-syncsource") + ": " + sourceUri;
                                  
        }
        else if (error != null) {
            // Check the exception error to display a proper message
            // FIXME: USE ALWAYS THE LANGUAGE TRANSLATION FOR THE UI MESSAGES!
           
            //this happens when the ds server is down                    
            if (error.indexOf("Unable to open connection") != -1) {
                return "Unable to open connection";
           
            //e.g. when the host name is wrong
            } else if (error.indexOf("Bad DNS Address") != -1) {
                return "Server name not found. Check the settings.";
           
            //e.g. when the network cable is not plugged 
            } else if (error.indexOf("DNSException") != -1) {//TODO: this is e.toString() in SyncManagerImpl.postRequest(). We should use e.getMsg()
                return "Unable to connect to a DNS. Check your Internet connection";
           
            } else if (error.indexOf("Connection timed out") != -1) {
                return "Connection timed out. Please retry";
           
            //e.g. when the end of stream has been reached unexpectedly during input
            } else if (error.indexOf("End of stream") != -1) {//java.io.EOFException
                return "Input stream interrupted. Please turn wireless on, or check the Server URL";//"End of stream has been reached unexpectedly during input"
               
            //e.g. when an incomplete server URI (without "http://") was entered in the Admin Tool
            } else if (error.indexOf("Protocol not found") != -1) {
                return "Check the Server URI in the Admin Tool. It must start with \"http://\"";
               
            } else if (error.indexOf("Improper data") != -1) {
               
                String exempligratia = "";
               
                if (remoteDBType.equals("calendar")) {
                    exempligratia = "\"events\" instead of \"scal\"";
                } else if (remoteDBType.equals("address book")) {
                    exempligratia = "\"contacts\" instead of \"scard\"";
                }
               
                return "Improper data from server for " + remoteDBType +
                       ". You must enter the name of a SIF source (e.g. " + exempligratia + ")";
           
            } else if (error.indexOf("Connection refused") != -1) {
                return sdh.getLanguage("error-connecting-to-the-server");
               
            } else if (error.indexOf(sdh.getLanguage("out-of-memory")) != -1) {
                return sdh.getLanguage("out-of-memory");
               
            } else if (ERROR_SERVER.equals(error)) {
                return sdh.getLanguage("internal-server-error");
               
            } else if (error.indexOf(ERROR_REFRESH_REQUIRED) >= 0) {//508  
                try {//ClassCastException with calendar events & contacts data
                   
                    if ("address book".equals(remoteDBType)) {
                        ContactDataStore dataStore = (ContactDataStore)DataStore.getDataStore(sourceUri);
                        dataStore.setLastTimestamp(0l);
                    } else if ("calendar".equals(remoteDBType)) {
                        EventDataStore dataStore = (EventDataStore)DataStore.getDataStore(sourceUri);
                        dataStore.setLastTimestamp(0l);
                    } else if ("mail".equals(remoteDBType)) {
                        MailDataStore dataStore = (MailDataStore)DataStore.getDataStore(sourceUri);
                        dataStore.setLastTimestamp(0l);
                    }
                }
                catch (DataAccessException e) {
                    StaticDataHelper.log("EXCEPTION in SyncClient.getSynchError: " + e.toString());
                }
               
                return "Refresh-Required";
            }
            // If the message is not known, and is available, return it.
            return error;
        }
        else {//error == null
            //if we return just 'error', the string "null" is printed on the device's screen!"
            sdh.log("[DEBUG]In SyncClient.getSynchError() the 'generic exception' is: " + error);
            return "A generic exception occurred";
        }
    }

    /**
     * AppScreen is an inner class that creates the home screen
     * for SyncClient on the BlackBerry. It extends MainScreen.
     *
     */
    class AppScreen extends MainScreen
    {
        private ConfigurationScreen configScreen;

        StaticDataHelper sdh = new StaticDataHelper();

        /**
         * Creates the home screen with all the UI components on it
         */
        public AppScreen()
        {
            Bitmap icon            = null;
            BitmapField iconField  = null;

            icon = Bitmap.getBitmapResource(IMAGE_LOGO);
            iconField = new BitmapField(icon, Field.FIELD_HCENTER);//Field is centered horizontally
           
            /*
             * Specifies the amount of horizontal
             * and vertical padding placed around
             * this field's contained bitmap image
             */
            iconField.setSpace(5, 5);

            configScreen = new ConfigurationScreen();

            setTitle(new LabelField(sdh.getLanguage("sync4j-bb-syncclient")));

            add(new LabelField(sdh.getLanguage("goto-menu-for-changing")));
            add(new LabelField(sdh.getLanguage("or-to-synchronize")));
            add(iconField);
        }

        /**
         * This creates a MenuItem containing the "Synchronize" option.
         * On selecting it, the user's data is synchronized.
         */
        private MenuItem syncMenu = new MenuItem(sdh.getLanguage("synchronize"), 10000, 9)
        {
            public void run() {
           
                /*
                 * if no message services are activated
                 * the session is null
                 */
                Session session = Session.getDefaultInstance();
                if (session == null)
                    showServiceWarning = true;   
                else
                    showServiceWarning = false;
               
                StaticDataHelper.log("### In MenuItem \"Synchronize\": session is " + Session.getDefaultInstance() +
                                         ", mailSyncAllowed is " + mailSyncAllowed +
                                         ", showServiceWarning is " + showServiceWarning);
                                       
                //wow!
                if (showServiceWarning)
                    Dialog.alert("No message services configured. Please activate the BlackBerry Email service in order to sync mail messages too");
                            
                synchronized (this) {      
                    thread = new Thread(SyncClient.this);
                    thread.start();
                }
            }
        };
       
        /**
         * This creates a MenuItem containing "Configure..." option.
         * Selecting the configure option, the user is directed to
         * the configuration screen.
         */
        private MenuItem configMenu = new MenuItem(sdh.getLanguage("configure"), 20000, 10)
        {
            public void run()
            {
                /*
                 * by pushing a screen, an event lock
                 * object has to be held to synchronize
                 * threads access on it
                 */
                synchronized(getEventLock())
                {
                    StaticDataHelper.log("### In MenuItem \"Configure\": session is " + Session.getDefaultInstance() +
                                         ", mailSyncAllowed is " + mailSyncAllowed +
                                         ", showServiceWarning is " + showServiceWarning);
                   
                    /*
                     * if no message services are activated
                     * the session is null
                     */
                    Session session = Session.getDefaultInstance();
                    if (session == null)
                    {
                        mailSyncAllowed = false;//used to build the config screen
                        showServiceWarning = true;   
                    }
                    else
                    {
                       // mailSyncAllowed = true;//used to build the config screen
                        showServiceWarning = false;
                    }
                   
                    StaticDataHelper.log("### In MenuItem \"Configure...\": session is " + Session.getDefaultInstance() +
                                         ", mailSyncAllowed is " + mailSyncAllowed +
                                         ", showServiceWarning is " + showServiceWarning);
                   
                    configScreen = new ConfigurationScreen();
                   
                    pushScreen(configScreen);
                   
                    //wow!
                    if (showServiceWarning)
                        Dialog.alert("No message services configured. Please activate the BlackBerry Email service in order to sync mail messages too");
                }
            }
        };
       
        /**
         * DEBUG
         * This creates a MenuItem containing the "Clean poller flag" option,
         * to avoid having to install the application every time you
         * need to test the functionality
         *
        private MenuItem cleanMenu = new MenuItem(("[Clean poller flag]"), 30000, 10)
        {
             public void run()
             {
                 synchronized(getEventLock())
                 {
                     PersistentStore.destroyPersistentObject(Poller.KEY);
                     displayStatus("DEBUG: Poller store deleted. You can synchronize now");
                 }
             }

        };
        */
       
        /**
         * A development helper menu entry
         *
        private MenuItem servicebookMenu = new MenuItem(("Show Service Book..."), 40000, 10)
        {
            public void run()
            {
                synchronized(getEventLock())
                {
                    ServiceBook servicebook = ServiceBook.getSB();
                    ServiceRecord[] list = servicebook.getRecords();
                    
                    StringBuffer buffer = new StringBuffer();
                    
                    if (list != null && list.length != 0)
                    {
                        int size = list.length;                    
                        for (int i = 0; i < size; i++)
                        {
                            buffer.append(i+1 + ") " + list[i].getDescription() + " [" + list[i].getCid() + "]");
                            //to avoid a blank line after the last line...
                            if (i < size-1)
                                buffer.append("\n");
                        }
                    }
                    else if (list.length == 0)
                    {
                        buffer.append("Service book is empty");
                    }
                       
                    Dialog.inform(buffer.toString());
                }
            }
        };
        */

        /**
         * The 'About' menu entry
         */
        private MenuItem aboutMenu = new MenuItem(("About..."), 50000, 10) {
            String version = "OfficeSync - v. " + VER + "\r\n\r\n";
            String license = "Copyright (C) 2003 - 2007 Funambol, Inc.\r\n\r\n" +
                             "This program is based on Funambol Blackberry Plugin Community Edition v. 3.0.8. " +
                             "This program is provided AS IS, without warranty licensed under AGPLV3. The Program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation including the additional permission set forth source code file header.\r\n\r\n" +
                             "The interactive user interfaces in modified source and object code versions of this program must display Appropriate Legal Notices, as required under Section 5 of the GNU Affero General Public License version 3.\r\n\r\n" +
                             "In accordance with Section 7(b) of the GNU Affero General Public License version 3, these Appropriate Legal Notices must retain the display of the \"Powered by Funambol\" logo. If the display of the logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices must display the words \"Powered by Funambol\". Funambol is a trademark of Funambol, Inc.";//TODO read a (n XML) file instead

            public void run() {
                synchronized(getEventLock()) {
                    Dialog.inform(version + license);
                }
            }
        };


       /**
         * Adds "Configure", "Synchronize", "Clean poller flag",
         * "Show service book", "About" menu items to the menu on
         * the home screen
         *
         * @param Menu Menu to which menuitems are to be added
         * @param int instance
         */
        public void makeMenu(Menu menu, int instance)
        {
            menu.add(syncMenu);
            menu.add(configMenu);
            //menu.add(cleanMenu);//DEBUG
            //menu.add(servicebookMenu);//DEBUG
            menu.add(aboutMenu);
        }

        /**
         * This method is invoked on user hitting the escape button when in home screen.
         * It prompts the user with a YES/NO dialog, if he wants to exit/not.
         * @param void.
         * @return void.
         */
        public boolean onClose()
        {
            //System.exit(0);
             this.getApplication().requestBackground();
             return true;
        }
    }

    /**
     * Is an inner class (member class) that creates
     * the configuration screen for configuring parameters
     * required for the SyncClient
     */
    class ConfigurationScreen extends MainScreen {

        //-------------------Private UI components
        private BasicEditField     homePageField          = null ;
        private BasicEditField     userNameField          = null ;
        private BasicEditField     contactSourceUriField  = null ;
        private BasicEditField     calendarSourceUriField = null ;
        private BasicEditField     mailSourceUriField     = null ;
        private PasswordEditField  passwordField          = null ;
        private BasicEditField     mailIDField            = null ;
        private BasicEditField     listeningPortField     = null;
        private BasicEditField     gatewayApnField        = null ;
        private BasicEditField     gatewayIpField         = null ;
        private BasicEditField     gatewayPortField       = null ;
       
       
        private CheckboxField      syncContactField       = null ;
        private CheckboxField      syncCalendarField      = null ;
        private CheckboxField      syncMailField          = null ;
        private CheckboxField      pollingField           = null ;
        private CheckboxField      smsField               = null ;
        private NumericChoiceField pollIntervalField      = null ;
        private  String[] choices                         = null ;
       
        //------Constructor
       
        /**
         * The constructor here creates the Configuration
         * screen with all the UI components on it and sets
         * default input values
         */
        public ConfigurationScreen() {
            StaticDataHelper sdh = new StaticDataHelper() ;
            Configuration c = new Configuration() ;
           
            setTitle(new LabelField(sdh.getLanguage("configure-sync4j-bb")));

            Log.debug("Username:" + c.userName);
            Log.debug("Sync Calendar: " + c.syncCalendar);
           
            userNameField           = new BasicEditField
                                        (sdh.getLanguage("user") + " " , c.userName );

            passwordField           = new PasswordEditField
                                        (sdh.getLanguage("password") + " " , c.password );

            homePageField           = new BasicEditField
                                        (sdh.getLanguage("homepage") + " \n" , c.syncUrl );
                                       
            listeningPortField      = new BasicEditField
                                        (sdh.getLanguage("alerting-port") + "  " ,
                                        c.listeningPort);
           
            mailIDField             = new BasicEditField
                                        (sdh.getLanguage("email-id") + "  " , c.mailAddress);
                                       
           
                                       
            mailSourceUriField      = new BasicEditField
                                        (sdh.getLanguage("source-uri-mail") + "  "  ,
                                        c.mailSourceUri);
            contactSourceUriField   = new BasicEditField
                                        (sdh.getLanguage("source-uri-contact") + "  "  ,
                                        c.contactSourceUri );

            calendarSourceUriField  = new BasicEditField
                                        (sdh.getLanguage("source-uri-calendar") + "  " ,
                                        c.calendarSourceUri );
                                       

            syncContactField        = new CheckboxField
                                        (sdh.getLanguage("enable-sync-contact")       ,
                                        c.syncContact );

            syncCalendarField       = new CheckboxField
                                        (sdh.getLanguage("enable-sync-calendar")      ,
                                        c.syncCalendar );
                                       
            syncMailField           = new CheckboxField
                                        (sdh.getLanguage("enable-sync-mail")      ,
                                        c.syncMail);
                                       
            pollingField            = new CheckboxField(
                                        sdh.getLanguage("enable-polling"),
                                        c.enablePolling);
                                      
            smsField                = new CheckboxField(
                                        sdh.getLanguage("enable-sms-server-alerted-sync"),
                                        c.enableSmsSync);
                                      
            gatewayApnField         = new BasicEditField
                                        (sdh.getLanguage("gateway-apn") + " "        ,
                                        c.gatewayApn );

            gatewayIpField          = new BasicEditField
                                        (sdh.getLanguage("gateway-ip") + " "         ,
                                        c.gatewayIp );

            gatewayPortField        = new BasicEditField
                                        (sdh.getLanguage("gateway-port") + " "      ,
                                        c.gatewayPort  ,
                                        6              ,
                                        EditField.FILTER_INTEGER );
           
            ///////////////////////////////////////////////////////////////////////////
           
         
            pollIntervalField  = new NumericChoiceField
                                   (sdh.getLanguage("polling-duration")+ "  "  ,
                                    1                                          ,//begin
                                    60                                         ,//end
                                    1                                          ,//increment
                                    Configuration.pollInterval - 1            );//initial index (not value!)
          
            SeparatorField separator1 = new SeparatorField();
            SeparatorField separator2 = new SeparatorField();
            SeparatorField separator3 = new SeparatorField();
            SeparatorField separator4 = new SeparatorField();
            SeparatorField separator5 = new SeparatorField();
           
            add(userNameField);
            add(passwordField);
            add(homePageField);
           
            add(separator1);
      
            add(syncContactField         );
            add(contactSourceUriField    );

            //if (newVersion) {
                add(separator2);           
                add(syncCalendarField);
                add(calendarSourceUriField);
            //}
           
            StaticDataHelper.log(">>>>>> In ConfigurationScreen() flag mailSyncAllowed is " + mailSyncAllowed);
            if (mailSyncAllowed) {
                add(separator3);
                add(syncMailField)
                add(mailSourceUriField);
                add(mailIDField);
                add(pollingField);
                add(pollIntervalField);
                add(separator4);
                add(smsField);//added for Server Alerted Notification
            }
           
            add(separator5);
            add(gatewayApnField);
            add(gatewayIpField);
            add(gatewayPortField);
        }

        /**
         * Populates the UI components with
         * previous settings, if available
         *
         *
        private void populateData() {
            StringVector data = null;
            Configuration c = new Configuration();
                       
            if (data != null) {
                homePageField.setText(c.syncUrl);
                userNameField.setText(c.userName);
                passwordField.setText(c.password);

                mailIDField.setText(c.mailAddress);
                mailSourceUriField.setText(c.mailSourceUri);
                contactSourceUriField.setText(c.contactSourceUri);
                calendarSourceUriField.setText(c.calendarSourceUri);
              
                syncContactField.setChecked(c.syncContact);
                syncCalendarField.setChecked(c.syncCalendar);
                syncMailField.setChecked(c.syncMail);
               
                gatewayApnField.setText(c.gatewayApn);
                gatewayIpField.setText(c.gatewayIp);
                gatewayPortField.setText(c.gatewayPort);
                listeningPortField.setText(c.listeningPort);

                pollingField.setChecked(c.enablePolling);
              
                // The index starts from 0
                int pollIdx = c.pollInterval - 1;
                pollIntervalField.setSelectedValue(pollIdx);
               
                smsField.setChecked(c.enableSmsSync);
            }
        }*/

        /**
         * This creates a MenuItem containing "Save" option.
         * on selecting the save option the configuration details are saved.
         */
        private MenuItem saveConfItem = new MenuItem(sdh.getLanguage("save"), 20000, 10) {

            public void run() {
                saveConfiguration();
            }

        };

        /**
         * Invoked when a user selects the "Save" option
         * from the menu in the configuration screen or
         * from the dialog when the user exits the
         * configuration screen. It saves changes on the
         * configuration into the persistant store
         *
         */
        public void saveConfiguration() {
           
            Log.debug("Entering SyncClient$ConfigurationScreen.saveConfiguration()");
               
            String homePage           = null ;
            String userName           = null ;
            String password           = null ;
            String gatewayApn         = null ;
            String gatewayIp          = null ;
            String gatewayPort        = null ;
            String contactSourceUri   = null ;
            String calendarSourceUri  = null ;
            String mailSourceUri      = null ;
            boolean syncContact       = false ;
            boolean syncCalendar      = false ;
            boolean syncMail          = false ;
            boolean enablePolling     = false ;
            boolean enableSmsSync     = false ;
            String mailID             = null ;
            String listeningPort      = null ;
            int pollInterval          = 5 ;
           
            int oldPollInterval;
           
            homePage                  = homePageField.getText().trim();
            contactSourceUri          = contactSourceUriField.getText().trim();
            calendarSourceUri         = calendarSourceUriField.getText().trim();
            mailSourceUri             = mailSourceUriField.getText().trim();      
           
            syncContact = syncContactField.getChecked();
            syncCalendar = syncCalendarField.getChecked();
            syncMail = syncMailField.getChecked();
            enablePolling = pollingField.getChecked();
            enableSmsSync = smsField.getChecked();

            userName      = userNameField.getText().trim();
            password      = passwordField.getText().trim();
            listeningPort = listeningPortField.getText().trim();
            mailID        = mailIDField.getText().trim();

            gatewayApn    = gatewayApnField.getText().trim();
            gatewayIp     = gatewayIpField.getText().trim();
            gatewayPort   = gatewayPortField.getText().trim();

            pollInterval  = pollIntervalField.getSelectedValue();
           
            if (syncMail && (mailID == null || mailSourceUri == null))
            {
                displayStatus(sdh.getLanguage("configuration-incomplete"));
                return;               
            }
            else if (syncMail && (mailID.equals("") || mailSourceUri.equals("")))
            {
                displayStatus(sdh.getLanguage("configuration-incomplete"));
                return;
            }
            
            if (homePage          == null ||
                contactSourceUri  == null ||
                calendarSourceUri == null ||
                userName          == null ||
                password          == null ) {
                   
                displayStatus(sdh.getLanguage("configuration-incomplete"));
                return;

            } else if (homePage.equals   ("") ||
                contactSourceUri.equals  ("") ||
                calendarSourceUri.equals ("") ||
                userName.equals          ("") ||
                password.equals          ("") ) {

                displayStatus(sdh.getLanguage("configuration-incomplete"));
                return;

            } else if ((homePage.indexOf("http") != 0) && (homePage.indexOf("https") != 0)) {

                displayStatus(sdh.getLanguage("homepage-not-correct"));
               
                return;
               
            } else {
              
                // Okay, save the configuration
                Configuration.syncUrl  = homePage;
                Configuration.userName = userName;
                Configuration.password = password;

                Configuration.syncContact = syncContact;
                Configuration.contactSourceUri = contactSourceUri;

                Configuration.syncCalendar = syncCalendar;
                Configuration.calendarSourceUri = calendarSourceUri;

                Configuration.syncMail = syncMail;
                Configuration.mailSourceUri = mailSourceUri;
                Configuration.mailAddress = mailID;
                Configuration.enablePolling = enablePolling;

                // Save old config for the check below
                oldPollInterval = Configuration.pollInterval;

                Configuration.pollInterval = pollInterval;
                Configuration.enableSmsSync = enableSmsSync;

                Configuration.gatewayApn = gatewayApn;
                Configuration.gatewayIp = gatewayIp;
                Configuration.gatewayPort = gatewayPort;
                Configuration.listeningPort = listeningPort;

                Configuration.save();

                displayStatus(sdh.getLanguage("data-properly-configured"));
            }
           

            if (enablePolling) {
                //pollerFlag = true;
               
                if (oldPollInterval != Configuration.pollInterval) {
                    if (pollerThread != null) {
                        if (pollerThread == Thread.currentThread()) {
                            pollerThread.interrupt();//to stop immediatly a sleeping poller...
                        }
                    }
                }
               
                Poller poller = new Poller();
                try {
                    poller.setSyncClientObj(SyncClient.this);
                } catch (Throwable t) {
                    StaticDataHelper.log("Exception " + t.getMessage() + " creating a new SyncClient object for the Poller: " + t.toString());
                }
               
                pollerThread = new Thread(poller);
                pollerThread.start();
           
            } {
                if (pollerThread != null) {
                    if (pollerThread == Thread.currentThread()) {
                        pollerThread.interrupt();//to stop immediatly a sleeping poller...
                    }
                }
                //pollerFlag = false;
            }
           
            // ------------------------------------------------------------------------------------------------------------------------------------
            if (enableSmsSync) {
               
                if (listenerSMS == null) {
                    listenerSMS = new SMSListener();
                }
               
                try {
                    listenerSMS.setSyncClientObj(SyncClient.this);
                } catch (Throwable t) {
                    StaticDataHelper.log("Exception " + t.getMessage() + " creating a new SyncClient object for the SMSListener: " + t.toString());
                }
               
                smsThread = new Thread(listenerSMS);
                smsThread.start();
                StaticDataHelper.log("[LOG] SMS listener thread STARTED because of new configuration");
                
            } else if (Configuration.enableSmsSync) {
                if (smsThread != null) {
                    if (smsThread.isAlive()) {
                        //smsThread.interrupt();//to stop immediatly an SMS listener, when conf changes
                        listenerSMS.stop();//to stop immediatly an SMS listener, when conf changes
                        listenerSMS = null;
                       
                        //the thread itself is exited while the flow returns from SMSListener.run()
                       
                        StaticDataHelper.log("[LOG] SMS listener thread STOPPED because of new configuration");
                    }
                }
            }
            // ------------------------------------------------------------------------------------------------------------------------------------
           
            popScreen(ConfigurationScreen.this);
        }

        /**
         * Adds "Save" menu item to the menu on Configuration screen
         *
         * @param Menu : menu to which save menuitem is to be added
         * @param int : instance
         * @return void.
         */
        public void makeMenu(Menu menu, int instance) {
            menu.add(saveConfItem);
        }

        /**
         * Invoked on user hitting the escape button.
         * It prompts the user with a dialog, if he wants to save/discard/cancel
         * the changes in configuration
         *
         * @param void
         * @return true if the screen closes, false otherwise
         */
        public boolean onClose()
        {
            int response = Dialog.ask(Dialog.D_SAVE,sdh.getLanguage("do-you-want-save"));

            if (Dialog.SAVE == response ) {
                   saveConfiguration();
                    
            } else if(Dialog.CANCEL == response) {
                    //displayStatus(sdh.getLanguage("no-changes-to-previous"));
                    return false;
            } else if (Dialog.DISCARD == response) {
                    popScreen(ConfigurationScreen.this);
                    displayStatus(sdh.getLanguage("no-changes-to-previous"));
            }

            return true;
        }
    }

    /**
     * This is the entry point for SyncClient Application. The thread
     * that calls this method (typically the main thread in the
     * application) becomes the event-dispatching thread, which will
     * execute all drawing and event-handling code
     *
     * @param s[] An array of strings passed on the command line
     *            as parameters for the <code>java</code> interpreter
     */
    public static void main(String s[]) throws Exception {
        SyncClient client = new SyncClient();
        client.enterEventDispatcher();
    }
}

TOP

Related Classes of com.funambol.syncclient.blackberry.SyncClient$ConfigurationScreen

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.