001: /*
002: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License version
007: * 2 only, as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful, but
010: * WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * General Public License version 2 for more details (a copy is
013: * included at /legal/license.txt).
014: *
015: * You should have received a copy of the GNU General Public License
016: * version 2 along with this work; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
018: * 02110-1301 USA
019: *
020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
021: * Clara, CA 95054 or visit www.sun.com if you need additional
022: * information or have any questions.
023: */
024:
025: package com.sun.midp.main;
026:
027: import com.sun.midp.midlet.*;
028: import com.sun.midp.security.*;
029: import com.sun.midp.events.EventQueue;
030: import com.sun.midp.lcdui.*;
031: import com.sun.midp.configurator.Constants;
032: import com.sun.midp.log.*;
033:
034: /**
035: * The class presents abstract MIDlet suite loader with routines to prepare
036: * runtime environment for a suite execution. The class provides generic
037: * scenario to load, start and terminate a MIDlet suite in the common way
038: * for both SVM and MVM modes. All the differences of SVM & MVM modes are
039: * designed as virtual or abstract methods.
040: */
041: abstract class AbstractMIDletSuiteLoader implements
042: MIDletSuiteExceptionListener {
043:
044: /** The ID of the MIDlte suite task Isolate */
045: protected int isolateId;
046:
047: /** The ID of the AMS task Isolate */
048: protected int amsIsolateId;
049:
050: /** Suite ID of the MIDlet suite */
051: protected int suiteId;
052:
053: /** External application ID that can be provided by native AMS */
054: protected int externalAppId;
055:
056: /** Name of the class to start MIDlet suite execution */
057: protected String midletClassName;
058:
059: /** Display name of a MIDlet suite */
060: protected String midletDisplayName;
061:
062: /** The arguments to start MIDlet suite with */
063: protected String args[];
064:
065: /**
066: * Inner class to request security token from SecurityInitializer.
067: * SecurityInitializer should be able to check this inner class name.
068: */
069: static private class SecurityTrusted implements
070: ImplicitlyTrustedClass {
071: }
072:
073: /** This class has a different security domain than the MIDlet suite */
074: protected static SecurityToken internalSecurityToken = SecurityInitializer
075: .requestToken(new SecurityTrusted());
076:
077: /** Event queue instance created for this MIDlet suite execution */
078: protected EventQueue eventQueue;
079:
080: /**
081: * MIDlet suite instance created and properly initialized for
082: * a MIDlet suite invocation.
083: */
084: protected MIDletSuite midletSuite;
085:
086: // The MIDlet suite environment contains a set of event-related
087: // objects needed for each MIDlet suite execution.
088:
089: /** Foreground Controller adapter. */
090: protected ForegroundController foregroundController;
091:
092: /** Event producer for various screen change events. */
093: protected DisplayEventProducer displayEventProducer;
094:
095: /**
096: * Provides interface for display preemption, creation and other
097: * functionality that can not be publicly added to a javax package.
098: */
099: protected DisplayEventListener displayEventListener;
100:
101: /** Event producer for all repaint events. */
102: protected RepaintEventProducer repaintEventProducer;
103:
104: /** Stores array of active displays for a MIDlet suite isolate. */
105: protected DisplayContainer displayContainer;
106:
107: /**
108: * Provides interface for display preemption, creation and other
109: * functionality that can not be publicly added to a javax package.
110: */
111: protected DisplayEventHandler displayEventHandler;
112:
113: /**
114: * Handles item events not associated directly with
115: * particular <code>Display</code>.
116: */
117: protected ItemEventConsumer itemEventConsumer;
118:
119: /** Starts and controls MIDlets through the lifecycle states. */
120: protected MIDletStateHandler midletStateHandler;
121:
122: /** The event listener for LCDUI events. */
123: protected LCDUIEventListener lcduiEventListener;
124:
125: /**
126: * Reports an error detected during MIDlet suite invocation.
127: * @param errorCode the error code to report
128: */
129: protected abstract void reportError(int errorCode, String details);
130:
131: /**
132: * Reports an error detected during MIDlet suite invocation.
133: * @param errorCode the error code to report
134: */
135: protected void reportError(int errorCode) {
136: reportError(errorCode, null);
137: }
138:
139: /**
140: * Allocates resources for a suite execution according to
141: * global resource policy.
142: *
143: * @return true in the case resources were successfully allocated,
144: * false otherwise
145: */
146: protected boolean allocateReservedResources() {
147: return true;
148: }
149:
150: /**
151: * Sets MIDlet suite arguments as temporary suite properties.
152: * Subclasses can override the method to export any other needed
153: * suite properties.
154: */
155: protected void setSuiteProperties() {
156: if (args != null) {
157: for (int i = 0; i < args.length; i++) {
158: if (args[i] != null) {
159: midletSuite.setTempProperty(internalSecurityToken,
160: "arg-" + i, args[i]);
161: }
162: }
163: }
164: }
165:
166: /** Core initialization of a MIDlet suite loader */
167: protected void init() {
168: // Init security tokens for core subsystems
169: SecurityInitializer.initSystem();
170:
171: eventQueue = EventQueue.getEventQueue(internalSecurityToken);
172: }
173:
174: /** Final actions to finish a MIDlet suite loader */
175: protected void done() {
176: eventQueue.shutdown();
177: }
178:
179: /**
180: * Creates all needed objects of a MIDlet suite environment, but
181: * only initialization that is done, will be to pass other created objects,
182: * and the current and AMS isolate IDs. It is mostly event-related
183: * objects, however subclasses can extend the environment with more
184: * specific parts
185: */
186: protected void createSuiteEnvironment() {
187: displayEventHandler = DisplayEventHandlerFactory
188: .getDisplayEventHandler(internalSecurityToken);
189:
190: displayEventProducer = new DisplayEventProducer(eventQueue);
191:
192: repaintEventProducer = new RepaintEventProducer(eventQueue);
193:
194: displayContainer = new DisplayContainer(internalSecurityToken,
195: isolateId);
196:
197: /*
198: * Because the display handler is implemented in a javax
199: * package it cannot created outside of the package, so
200: * we have to get it after the static initializer of display the class
201: * has been run and then hook up its objects.
202: */
203: displayEventHandler.initDisplayEventHandler(
204: displayEventProducer, foregroundController,
205: repaintEventProducer, displayContainer);
206:
207: displayEventListener = new DisplayEventListener(eventQueue,
208: displayContainer);
209:
210: /* Bad style of type casting, but DisplayEventHandlerImpl
211: * implements both DisplayEventHandler & ItemEventConsumer IFs */
212: itemEventConsumer = (ItemEventConsumer) displayEventHandler;
213:
214: lcduiEventListener = new LCDUIEventListener(
215: internalSecurityToken, eventQueue, itemEventConsumer);
216: }
217:
218: /**
219: * Does all initialization for already created objects of a MIDlet suite
220: * environment. Subclasses can also extend the initialization with
221: * various global system initializations needed for all suites.
222: * The MIDlet suite has been created at this point, so it can be
223: * used to initialize any per suite data.
224: */
225: protected void initSuiteEnvironment() {
226: displayEventHandler.initSuiteData(midletSuite.isTrusted());
227: }
228:
229: /**
230: * Handles exception occurred during MIDlet suite execution.
231: * @param t exception instance
232: */
233: public abstract void handleException(Throwable t);
234:
235: /** Restricts suite access to internal API */
236: protected void restrictAPIAccess() {
237: // IMPL_NOTE: No restrictions by default
238: }
239:
240: /**
241: * Start MIDlet suite in the prepared environment
242: * @throws Exception can be thrown during execution
243: */
244: protected void startSuite() throws Exception {
245: midletStateHandler.startSuite(this , midletSuite, externalAppId,
246: midletClassName);
247: }
248:
249: /** Closes suite and unlock native suite locks */
250: protected void closeSuite() {
251: if (midletSuite != null) {
252: /* When possible, don't wait for the finalizer
253: * to unlock the suite. */
254: midletSuite.close();
255: }
256: }
257:
258: /**
259: * Checks whether an executed MIDlet suite has requested
260: * for a system shutdown. User MIDlets most probably have
261: * no right for it, however Java AMS MIDlet could do it.
262: */
263: protected void checkForShutdown() {
264: // IMPL_NOTE: No checks for shutdown by default
265: }
266:
267: /**
268: * Explicitly requests suite loader exit after MIDlet
269: * suite execution is finished and created environment is done.
270: */
271: protected abstract void exitLoader();
272:
273: /**
274: * Creates MIDlet suite instance by suite ID, the
275: *
276: * @return MIDlet suite to load
277: *
278: * @throws Exception in the case MIDlet suite can not be
279: * created because of a security reasons or some problems
280: * related to suite storage
281: */
282: protected abstract MIDletSuite createMIDletSuite() throws Exception;
283:
284: /**
285: * Inits MIDlet suite runtime environment and start a MIDlet
286: * suite with it
287: */
288: protected void runMIDletSuite() {
289: // WARNING: Don't add any calls before this!
290: //
291: // The core init of a MIDlet suite task should be able
292: // to perform the very first initializations of the environment
293: init();
294:
295: try {
296: /*
297: * Prepare MIDlet suite environment, classes that only need
298: * the isolate ID can be create here.
299: */
300: createSuiteEnvironment();
301:
302: /* Check to see that all of the core object are created. */
303: if (foregroundController == null
304: || displayEventProducer == null
305: || repaintEventProducer == null
306: || displayContainer == null
307: || displayEventHandler == null
308: || itemEventConsumer == null
309: || lcduiEventListener == null
310: || midletStateHandler == null) {
311:
312: throw new RuntimeException(
313: "Suite environment not complete.");
314: }
315:
316: // Regard resource policy for the suite task
317: if (!allocateReservedResources()) {
318: reportError(Constants.MIDLET_RESOURCE_LIMIT);
319: return;
320: }
321:
322: // Create suite instance ready for start
323: midletSuite = createMIDletSuite();
324:
325: if (midletSuite == null) {
326: reportError(Constants.MIDLET_SUITE_NOT_FOUND);
327: return;
328: }
329:
330: if (!midletSuite.isEnabled()) {
331: reportError(Constants.MIDLET_SUITE_DISABLED);
332: return;
333: }
334:
335: /*
336: * Now that we have the suite and reserved its resources
337: * we can initialize any classes that need MIDlet Suite
338: * information.
339: */
340: initSuiteEnvironment();
341:
342: // Export suite arguments as properties, so well
343: // set any other properties to control a suite
344: setSuiteProperties();
345:
346: // Restrict suite access to internal API
347: restrictAPIAccess();
348:
349: if (Logging.REPORT_LEVEL <= Logging.WARNING) {
350: Logging.report(Logging.WARNING, LogChannels.LC_CORE,
351: "MIDlet suite task starting a suite");
352: }
353:
354: // Blocking call to start MIDlet suite
355: // in the prepared environment
356: startSuite();
357:
358: // Check for shutdown possibly requested from the suite
359: checkForShutdown();
360:
361: if (Logging.REPORT_LEVEL <= Logging.WARNING) {
362: Logging.report(Logging.INFORMATION,
363: LogChannels.LC_CORE,
364: "MIDlet suite loader exiting");
365: }
366:
367: } catch (Throwable t) {
368: handleException(t);
369:
370: } finally {
371: closeSuite();
372: done();
373: exitLoader();
374: }
375: }
376: }
|