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