javaextensions/pim/javasrc/com/nokia/mj/impl/pim/PIMManager.java
branchRCL_3
changeset 19 04becd199f91
child 67 63b81d807542
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  PIM singleton implementation.
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 // PACKAGE
       
    20 package com.nokia.mj.impl.pim;
       
    21 
       
    22 // IMPORTS
       
    23 
       
    24 import javax.microedition.pim.PIM;
       
    25 import javax.microedition.pim.PIMException;
       
    26 import javax.microedition.pim.PIMItem;
       
    27 import javax.microedition.pim.PIMList;
       
    28 import java.io.UnsupportedEncodingException;
       
    29 import com.nokia.mj.impl.pim.ErrorString;
       
    30 import com.nokia.mj.impl.pim.GenericException;
       
    31 import com.nokia.mj.impl.rt.support.ApplicationUtils;
       
    32 import com.nokia.mj.impl.rt.support.Finalizer;
       
    33 import com.nokia.mj.impl.rt.support.ShutdownListener;
       
    34 import com.nokia.mj.impl.security.utils.SecurityPromptMessage;
       
    35 import com.nokia.mj.impl.pim.utils.NativeError;
       
    36 
       
    37 
       
    38 // CLASS DEFINITION
       
    39 /**
       
    40  * PIM singleton implementation. PIM class acts as a starting point to the PIM
       
    41  * API. Only single instance of the class is created and that instance is
       
    42  * accessed through an accessor method. The instance is created when it is
       
    43  * requested for the first time.
       
    44  *
       
    45  * PIMLists are created when lists are being opened. The list opening operation
       
    46  * is first delegated to the native side, where the native side peer object to
       
    47  * the list is created. Then the Java side list is created and initialized with
       
    48  * a reference to its native side counterpart.
       
    49  *
       
    50  * Versit conversion operations are mostly implemented in the native side (the
       
    51  * actual parsing) but some logic needs to be implemented in the Java side
       
    52  * (cutting the input stream into such pieces that can be passed through the JNI
       
    53  * etc.)
       
    54  */
       
    55 public final class PIMManager extends PIM
       
    56 {
       
    57 
       
    58     // Constants
       
    59 
       
    60     // Static data
       
    61 
       
    62     /** The single instance of PIMManager. */
       
    63     private static PIMManager sInstance = null;
       
    64 
       
    65     // Member data
       
    66 
       
    67     /** Finalizer. */
       
    68     private Finalizer iFinalizer;
       
    69 
       
    70     /** Handle to PIMManager native side. */
       
    71     private int iManagerHandle;
       
    72 
       
    73     /** Serializer. */
       
    74     private Serializer iSerializer;
       
    75 
       
    76     // Methods
       
    77 
       
    78     /**
       
    79      * Provides the single instance of PIMManager. Creates an Event Server and
       
    80      * the PIMManager native side.
       
    81      *
       
    82      * @par Notes:
       
    83      * @li This method is coupled with the \ref
       
    84      *     javax.microedition.pim.PIM.getInstance() method, which must delegate
       
    85      *     the operation immediately to this operation.
       
    86      */
       
    87     public synchronized static PIM getInstance()
       
    88     {
       
    89         if (sInstance == null)
       
    90         {
       
    91             sInstance = new PIMManager();
       
    92         }
       
    93 
       
    94         return sInstance;
       
    95     }
       
    96 
       
    97     /**
       
    98      * Creates PIMManager.
       
    99      * Direct creation of a PIMManager is prohibited.
       
   100      */
       
   101     private PIMManager()
       
   102     {
       
   103         super();
       
   104         setShutdownListener();
       
   105         iFinalizer = registerForFinalization();
       
   106         int[] error = new int[1];
       
   107         iManagerHandle = _createPIMManager(error);
       
   108         if (!NativeError.checkSuccess(error[0]))
       
   109         {
       
   110             throw new GenericException(ErrorString.GENERAL_ERROR_COLON + error[0]);
       
   111         }
       
   112 
       
   113         iSerializer = new Serializer(iManagerHandle);
       
   114     }
       
   115 
       
   116     /**
       
   117      * Disposes the PIMManager native peer and Event Source, if the handles are
       
   118      * valid. Invalid (negative) handles indicate that their creation failed in
       
   119      * the first place.
       
   120      */
       
   121     public Finalizer registerForFinalization()
       
   122     {
       
   123         return new Finalizer()
       
   124         {
       
   125             public void finalizeImpl()
       
   126             {
       
   127                 doFinalize();
       
   128             }
       
   129         };
       
   130     }
       
   131 
       
   132     void doFinalize()
       
   133     {
       
   134         if (iFinalizer == null)
       
   135         {
       
   136             return;
       
   137         }
       
   138         iFinalizer = null;
       
   139 
       
   140         if (iManagerHandle != 0)
       
   141         {
       
   142             _dispose(iManagerHandle);
       
   143             iManagerHandle = 0;
       
   144         }
       
   145     }
       
   146 
       
   147     /**
       
   148      * Registers for shutdown listener
       
   149      */
       
   150     private void setShutdownListener()
       
   151     {
       
   152         // Get the insatnce of ApplicationUtils.
       
   153         ApplicationUtils appUtils = ApplicationUtils.getInstance();
       
   154 
       
   155         // Get the name of the application.
       
   156         appUtils.addShutdownListener(new ShutdownListener()
       
   157         {
       
   158             public void shuttingDown()
       
   159             {
       
   160 
       
   161                 if (iManagerHandle != 0)
       
   162                 {
       
   163                     _dispose(iManagerHandle);
       
   164                     iManagerHandle = 0;
       
   165                 }
       
   166             }
       
   167 
       
   168         });
       
   169     }
       
   170 
       
   171     /**
       
   172      * Provides the handle to the native side PIM Manager. Needed by some other
       
   173      * implementation classes in this package.
       
   174      */
       
   175     int managerHandle()
       
   176     {
       
   177         return iManagerHandle;
       
   178     }
       
   179 
       
   180     // Methods from PIM
       
   181 
       
   182     public synchronized PIMList openPIMList(int aPimListType, int aMode)
       
   183     throws PIMException
       
   184     {
       
   185         return doOpenPIMList(aPimListType, aMode, null);
       
   186     }
       
   187 
       
   188     public synchronized PIMList openPIMList(int aPimListType, int aMode,
       
   189                                             String aName) throws PIMException
       
   190     {
       
   191         if (aName == null)
       
   192         {
       
   193             throw new NullPointerException(ErrorString.OPENING_LISTS_FAILED_COLON +
       
   194                                            ErrorString.LIST_NAME_IS_NULL);
       
   195         }
       
   196 
       
   197         return doOpenPIMList(aPimListType, aMode, aName);
       
   198     }
       
   199 
       
   200     public synchronized String[] listPIMLists(int aPimListType)
       
   201     {
       
   202         if (aPimListType != PIM.CONTACT_LIST && aPimListType != PIM.EVENT_LIST
       
   203                 && aPimListType != PIM.TODO_LIST)
       
   204         {
       
   205             throw new java.lang.IllegalArgumentException(ErrorString.LISTING_FAILED_DOT +
       
   206                     ErrorString.INVALID_LIST_TYPE_COLON + aPimListType);
       
   207         }
       
   208         // Ensure permission
       
   209         getPermission(aPimListType, PIM.READ_ONLY);
       
   210 
       
   211         int[] error = new int[1];
       
   212 
       
   213         String[] lists = _listPIMLists(iManagerHandle, aPimListType, error);
       
   214         NativeError.handleListPIMListError(error[0]);
       
   215 
       
   216         return lists;
       
   217     }
       
   218 
       
   219     public synchronized PIMItem[] fromSerialFormat(java.io.InputStream aIs,
       
   220             String aEnc) throws PIMException, UnsupportedEncodingException
       
   221     {
       
   222         return iSerializer.fromSerialFormat(aIs, aEnc);
       
   223     }
       
   224 
       
   225     public synchronized void toSerialFormat(PIMItem aItem,
       
   226                                             java.io.OutputStream aOs, String aEnc, String aDataFormat)
       
   227     throws PIMException, UnsupportedEncodingException
       
   228     {
       
   229         iSerializer.toSerialFormat(aItem, aOs, aEnc, aDataFormat);
       
   230     }
       
   231 
       
   232     public synchronized String[] supportedSerialFormats(int aPimListType)
       
   233     {
       
   234         return iSerializer.supportedSerialFormats(aPimListType);
       
   235     }
       
   236 
       
   237 
       
   238     /**
       
   239      * getPermission
       
   240      * Ensures permissions for PIM operations.
       
   241      * The possible operations in this case are reading from
       
   242      * the list or writing to the list. Note that read and write permission
       
   243      * must be handled separately since there is no dialog for READ_WRITE
       
   244      * permission mode.
       
   245      *
       
   246      * @param aListType The accessed PIM API list type. PIM.CONTACT_LIST,
       
   247      *                  PIM.EVENT_LIST or PIM.TODO_LIST
       
   248      * @param aMode     The used mode. PIM.READ_ONLY or PIM.WRITE_ONLY. This
       
   249      *                  function throws IllegalArgumentException of some other
       
   250      *                  mode is passed as a parameter
       
   251      */
       
   252     public void  getPermission(int aListType, int aMode)
       
   253     {
       
   254         // This function supports PIM.READ_ONLY or PIM.WRITE_ONLY modes
       
   255         // since PIM.READ_WRITE cannot be used to check which type of
       
   256         // an operation is requested
       
   257         if (aMode != PIM.READ_ONLY &&
       
   258                 aMode != PIM.WRITE_ONLY)
       
   259         {
       
   260             throw new IllegalArgumentException();
       
   261         }
       
   262 
       
   263         ApplicationUtils appUtils = ApplicationUtils.getInstance();
       
   264         String action = null;
       
   265         if (aMode == PIM.WRITE_ONLY)
       
   266         {
       
   267             switch (aListType)
       
   268             {
       
   269             case PIM.CONTACT_LIST:
       
   270                 action = PIMPermissionImpl.ACTION_WRITE_CONTACTS;
       
   271                 break;
       
   272             case PIM.EVENT_LIST:
       
   273                 action = PIMPermissionImpl.ACTION_WRITE_EVENTS;
       
   274                 break;
       
   275             case PIM.TODO_LIST:
       
   276                 action = PIMPermissionImpl.ACTION_WRITE_TODOS;
       
   277                 break;
       
   278             }
       
   279         }
       
   280         else
       
   281         {
       
   282             switch (aListType)
       
   283             {
       
   284             case PIM.CONTACT_LIST:
       
   285                 action = PIMPermissionImpl.ACTION_READ_CONTACTS;
       
   286                 break;
       
   287             case PIM.EVENT_LIST:
       
   288                 action = PIMPermissionImpl.ACTION_READ_EVENTS;
       
   289                 break;
       
   290             case PIM.TODO_LIST:
       
   291                 action = PIMPermissionImpl.ACTION_READ_TODOS;
       
   292                 break;
       
   293             }
       
   294         }
       
   295         PIMPermissionImpl per = new PIMPermissionImpl("pim://*", action);
       
   296         // Ensure permission from PIM API security
       
   297         appUtils.checkPermission(per);
       
   298     }
       
   299 
       
   300 
       
   301     // New private methods
       
   302     /**
       
   303      * Common implementation of the list opening. Arguments and permissions are
       
   304      * pre-checked.
       
   305      *
       
   306      * @param aName
       
   307      *            If null, default list is opened.
       
   308      */
       
   309     private PIMList doOpenPIMList(int aPimListType, int aMode, String aName)
       
   310     throws PIMException
       
   311     {
       
   312         if (aPimListType != PIM.CONTACT_LIST && aPimListType != PIM.EVENT_LIST
       
   313                 && aPimListType != PIM.TODO_LIST)
       
   314         {
       
   315             throw new java.lang.IllegalArgumentException(
       
   316                 ErrorString.INVALID_LIST_TYPE_COLON + aPimListType);
       
   317         }
       
   318 
       
   319         if (aMode != PIM.READ_ONLY && aMode != PIM.WRITE_ONLY
       
   320                 && aMode != PIM.READ_WRITE)
       
   321         {
       
   322             throw new java.lang.IllegalArgumentException(
       
   323                 ErrorString.INVALID_MODE_COLON + aMode);
       
   324         }
       
   325 
       
   326         // Both permissions must be checked separately if aMode is
       
   327         // PIM.READ_WRITE
       
   328         if (aMode == PIM.READ_WRITE)
       
   329         {
       
   330             // First ensure read access permission
       
   331             // Get localized text info for the security dialog
       
   332             getPermission(aPimListType, PIM.READ_ONLY);
       
   333             getPermission(aPimListType, PIM.WRITE_ONLY);
       
   334 
       
   335         }
       
   336         else
       
   337         {
       
   338             getPermission(aPimListType, aMode);
       
   339         }
       
   340         int[] error = new int[1];
       
   341         int listHandle = _openPIMList(
       
   342 
       
   343                              iManagerHandle, aPimListType, aName, error); // if null, open default
       
   344         // list
       
   345         NativeError.handleOpenPIMListError(error[0], aPimListType, aName);
       
   346 
       
   347 
       
   348         // Create new pim list of right type
       
   349         PIMListImpl pimList = null;
       
   350 
       
   351         switch (aPimListType)
       
   352         {
       
   353         case PIM.CONTACT_LIST:
       
   354         {
       
   355             pimList = new ContactListImpl(listHandle, aMode);
       
   356             break;
       
   357         }
       
   358 
       
   359         case PIM.EVENT_LIST:
       
   360         {
       
   361             pimList = new EventListImpl(listHandle, aMode);
       
   362             break;
       
   363         }
       
   364 
       
   365         case PIM.TODO_LIST:
       
   366         {
       
   367             pimList = new ToDoListImpl(listHandle, aMode);
       
   368             break;
       
   369         }
       
   370 
       
   371         default:
       
   372         {
       
   373             // We should never end up here
       
   374             throw new PIMException(ErrorString.GENERAL_ERROR,
       
   375                                    PIMException.GENERAL_ERROR);
       
   376         }
       
   377         }
       
   378 
       
   379         return pimList;
       
   380     }
       
   381 
       
   382 
       
   383     // Native operations
       
   384     /**
       
   385      * Creates PIMManager native side.
       
   386      *
       
   387      * @return Handle to the native side PIMManager.
       
   388      */
       
   389     private native int _createPIMManager(int[] aError);
       
   390 
       
   391     private native void _dispose(int aPIMManagerHandle);
       
   392 
       
   393     /**
       
   394      * @param aPimlistName
       
   395      *            List name. If null, default list is opened.
       
   396      *
       
   397      * @return Handle to new native side PIM list of given type or negative
       
   398      *         value on error.
       
   399      */
       
   400     private native int _openPIMList(int aManagerHandle, int aPimListType,
       
   401                                     String aPimListName, int[] aError);
       
   402 
       
   403     private native String[] _listPIMLists(int aManagerHandle, int aPimListType,
       
   404                                           int[] aError);
       
   405 
       
   406 }
       
   407 
       
   408 // End of file