|
1 /* |
|
2 * Copyright (c) 2005-2007 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: Container for controls. |
|
15 * |
|
16 */ |
|
17 |
|
18 package com.nokia.amms; |
|
19 |
|
20 import javax.microedition.media.Control; |
|
21 import javax.microedition.media.Controllable; |
|
22 import com.nokia.amms.ModuleBase; |
|
23 import com.nokia.amms.control.ControlImpl; |
|
24 import com.nokia.mj.impl.utils.Logger; |
|
25 import java.util.Hashtable; |
|
26 import java.util.Enumeration; |
|
27 |
|
28 /** |
|
29 * ControlContainer class creates java control objects according to a classname |
|
30 * which is got from native control object. Created controls are accessible |
|
31 * through Controllable interface which is implemented in this class. |
|
32 */ |
|
33 public class ControlContainer implements Controllable |
|
34 { |
|
35 /** |
|
36 * Default control package. Used when getting control with |
|
37 * getControl method which appends default control package if package is |
|
38 * not specified. |
|
39 */ |
|
40 static final String CONTROL_DEFAULT_PACKAGE = |
|
41 "javax.microedition.media.control."; |
|
42 |
|
43 /** |
|
44 * Package where control implementation are. |
|
45 */ |
|
46 static final String PRIVATE_PACKAGE = "com.nokia"; |
|
47 |
|
48 /** |
|
49 * Hashtable containing controls identified with a full package name. |
|
50 * All control names starts with iDefaultPackage. |
|
51 */ |
|
52 private final Hashtable iControls = new Hashtable(); |
|
53 |
|
54 /** |
|
55 * Creates new ControlContainer. |
|
56 */ |
|
57 private ControlContainer() |
|
58 { |
|
59 } |
|
60 |
|
61 /** |
|
62 * Create new ControlContainer and populates the controls. |
|
63 * |
|
64 * @param aDefaultPackege Default control package. Used when getting control |
|
65 * with getControl method which appends default control package if package |
|
66 * is not specified. |
|
67 * @param aEventSourceHandle Handle to native event source. |
|
68 * @param aNativeHandle Handle to native control source. |
|
69 * @param aModule Module where the controls belong to. |
|
70 */ |
|
71 public static final ControlContainer populateControls( |
|
72 int aEventSourceHandle, |
|
73 int aNativeHandle, |
|
74 ModuleBase aModule) |
|
75 { |
|
76 ControlContainer container = new ControlContainer(); |
|
77 |
|
78 // Get amount of controls in native object. |
|
79 int controlCount = _getControlsCount(aEventSourceHandle, |
|
80 aNativeHandle); |
|
81 |
|
82 // Create java object for each native objects. |
|
83 for (int i = 0; i < controlCount; i++) |
|
84 { |
|
85 // Get handle to native object at index i |
|
86 int controlHandle = _getControlHandle(aEventSourceHandle, |
|
87 aNativeHandle, |
|
88 i); |
|
89 |
|
90 // Get controls class name which will be used to create java object |
|
91 String className = _getControlClassName(aEventSourceHandle, |
|
92 controlHandle); |
|
93 |
|
94 // create java instance |
|
95 Control control = createControl(className, |
|
96 controlHandle, |
|
97 aEventSourceHandle, |
|
98 aModule); |
|
99 |
|
100 // Add package if it does not exists |
|
101 if (className.indexOf('.') < 0) |
|
102 { |
|
103 className = CONTROL_DEFAULT_PACKAGE + className; |
|
104 } |
|
105 container.iControls.put(className, control); |
|
106 } |
|
107 |
|
108 // population succeed, return created collection |
|
109 return container; |
|
110 } |
|
111 |
|
112 /** |
|
113 * Implements method defined in javax.microedition.media.Controllable. |
|
114 * |
|
115 * @see javax.microedition.media.Controllable |
|
116 * @param aControlType the class name of the Control. The class name should |
|
117 * be given either as the fully-qualified name of the class; or if the |
|
118 * package of the class is not given, the package |
|
119 * javax.microedition.media.control is assumed. |
|
120 * @return the object that implements the control, or null. |
|
121 */ |
|
122 public Control getControl(String aControlType) |
|
123 { |
|
124 if (aControlType == null) |
|
125 { |
|
126 Logger.ELOG(Logger.EJavaMMAPI, |
|
127 "ControlContainer::getControl parameter was null"); |
|
128 throw new IllegalArgumentException("argument was null"); |
|
129 } |
|
130 |
|
131 String controlType = aControlType; |
|
132 |
|
133 // check if package name exists |
|
134 if (controlType.indexOf(".") == -1) |
|
135 { |
|
136 // add package name |
|
137 controlType = CONTROL_DEFAULT_PACKAGE + aControlType; |
|
138 } |
|
139 Control control = (Control)iControls.get(controlType); |
|
140 |
|
141 // If control does not exists with default name, check if there is |
|
142 // is a control with same type ( extends the given class name ). |
|
143 if (control == null) |
|
144 { |
|
145 try |
|
146 { |
|
147 // try to create class for control |
|
148 Class controlClass = Class.forName(controlType); |
|
149 |
|
150 Enumeration elements = iControls.elements(); |
|
151 |
|
152 // search if any control is same type that requested control |
|
153 while (elements.hasMoreElements() && |
|
154 control == null) |
|
155 { |
|
156 Control tmpControl = (Control)elements.nextElement(); |
|
157 if (controlClass.isInstance(tmpControl)) |
|
158 { |
|
159 // control is found |
|
160 control = tmpControl; |
|
161 } |
|
162 } |
|
163 } |
|
164 catch (ClassNotFoundException cnfe) // the class could not be found |
|
165 { |
|
166 // Exception is ignored and null is returned from this method |
|
167 Logger.ELOG(Logger.EJavaMMAPI, |
|
168 "ControlContainer::getControl ", |
|
169 cnfe); |
|
170 } |
|
171 catch (Error e) // the function failed for any other reason. |
|
172 { |
|
173 // Error is ignored and null is returned from this method |
|
174 Logger.ELOG(Logger.EJavaMMAPI, |
|
175 "ControlContainer::getControl ", |
|
176 e); |
|
177 } |
|
178 } |
|
179 return control; |
|
180 } |
|
181 |
|
182 /** |
|
183 * Implements method defined in javax.microedition.media.Controllable. |
|
184 * |
|
185 * @see javax.microedition.media.Controllable |
|
186 * @return the collection of Control objects. |
|
187 */ |
|
188 public Control[] getControls() |
|
189 { |
|
190 Control[] controls = new Control[ iControls.size()]; |
|
191 Enumeration elements = iControls.elements(); |
|
192 int i = 0; |
|
193 // Put all controls to array |
|
194 while (elements.hasMoreElements()) |
|
195 { |
|
196 controls[ i ] = (Control)elements.nextElement(); |
|
197 i++; |
|
198 } |
|
199 return controls; |
|
200 } |
|
201 |
|
202 /** |
|
203 * Invalidates the controls stored in this container. |
|
204 * After this using controls in Java side will throw |
|
205 * RuntimeException. |
|
206 */ |
|
207 public void invalidateControls() |
|
208 { |
|
209 Enumeration elements = iControls.elements(); |
|
210 |
|
211 while (elements.hasMoreElements()) |
|
212 { |
|
213 // All controls are instances of ControlImpl class. |
|
214 ControlImpl control = (ControlImpl)elements.nextElement(); |
|
215 control.invalidateControl(); |
|
216 } |
|
217 } |
|
218 |
|
219 /** |
|
220 * Creates new Control instance. |
|
221 * All control classes must be in iPrivatePackage package and |
|
222 * extend the ControlImpl base class. Created control is initialized |
|
223 * with native control handle and eventsource handle. |
|
224 * |
|
225 * @param aClassName Control's class name without the package. |
|
226 * @param aControlHandle Handle to native control. |
|
227 * @param aModule Module where the control belongs to. |
|
228 * @return created control |
|
229 */ |
|
230 static private final Control createControl(String aClassName, |
|
231 int aControlHandle, |
|
232 int aEventSourceHandle, |
|
233 ModuleBase aModule) |
|
234 { |
|
235 ControlImpl control = null; |
|
236 |
|
237 // Try to make control instance. If instantion fails, it is an internal |
|
238 // error and can only occur in development time. |
|
239 try |
|
240 { |
|
241 Class controlClass = |
|
242 Class.forName(PRIVATE_PACKAGE + |
|
243 aClassName); |
|
244 control = (ControlImpl)controlClass.newInstance(); |
|
245 control.initControl(aEventSourceHandle, aControlHandle, aModule); |
|
246 } |
|
247 catch (InstantiationException ie) |
|
248 { |
|
249 throw new OutOfMemoryError(ie.getMessage()); |
|
250 } |
|
251 catch (IllegalAccessException iae) |
|
252 { |
|
253 throw new OutOfMemoryError(iae.getMessage()); |
|
254 } |
|
255 catch (ClassNotFoundException cnfe) |
|
256 { |
|
257 throw new OutOfMemoryError(cnfe.getMessage()); |
|
258 } |
|
259 return control; |
|
260 } |
|
261 |
|
262 |
|
263 /** |
|
264 * Return the amount of controls in native control source. |
|
265 * |
|
266 * @param aEventSourceHandle Handle to native event source. |
|
267 * @param aNativeHandle Handle to native control source object. |
|
268 */ |
|
269 private static native int _getControlsCount(int aEventSourceHandle, |
|
270 int aNativeHandle); |
|
271 |
|
272 /** |
|
273 * Return native handle to control at specified index. |
|
274 * |
|
275 * @param aEventSourceHandle Handle to native event source. |
|
276 * @param aNativeHandle Handle to native control source object. |
|
277 * @param aControlIndex Control's index. |
|
278 */ |
|
279 private static native int _getControlHandle(int aEventSourceHandle, |
|
280 int aNativeHandle, |
|
281 int aControlIndex); |
|
282 /** |
|
283 * Returns the control class name that can be used to instantiate Java |
|
284 * object. |
|
285 * |
|
286 * @param aEventSourceHandle Handle to native event source. |
|
287 * @param aControlHandle Handle to native control. |
|
288 */ |
|
289 private static native String _getControlClassName(int aEventSourceHandle, |
|
290 int aControlHandle); |
|
291 |
|
292 |
|
293 } |