|
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 |