001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.midp.installer;
028:
029: import com.sun.cldchi.jvm.JVM;
030: import com.sun.midp.midletsuite.MIDletSuiteStorage;
031: import com.sun.midp.midlet.MIDletSuite;
032: import com.sun.midp.i18n.Resource;
033: import com.sun.midp.i18n.ResourceConstants;
034: import com.sun.midp.main.MIDletSuiteVerifier;
035: import com.sun.midp.log.Logging;
036: import com.sun.midp.log.LogChannels;
037:
038: import javax.microedition.midlet.MIDlet;
039: import javax.microedition.lcdui.*;
040: import java.io.IOException;
041:
042: /**
043: * The Graphical MIDlet suite classes verifier application.
044: * <p>
045: */
046: public class SuiteVerifier extends MIDlet implements CommandListener {
047:
048: /** Display for this MIDlet */
049: private Display display;
050: /** Command object for "Back" command in the suite verification form */
051: private Command backCommand;
052: /** Displays the progress of the verification */
053: private Form progressForm;
054: /** Gauge for progress form index. */
055: private int progressGaugeIndex;
056:
057: /** Path to the JAR package to be verified */
058: private String jarPath;
059: /** Suite ID of the suite whose classes are verified */
060: private int suiteId;
061: /** Suite storage */
062: private MIDletSuiteStorage suiteStorage;
063:
064: /**
065: * Create and initialize a new discovery application MIDlet.
066: * The saved URL is retrieved and the list of MIDlets are retrieved.
067: */
068: public SuiteVerifier() {
069: display = Display.getDisplay(this );
070:
071: String strSuiteId = getAppProperty("arg-0");
072: try {
073: suiteId = Integer.parseInt(strSuiteId);
074: } catch (RuntimeException ex) {
075: suiteId = MIDletSuite.UNUSED_SUITE_ID;
076: }
077:
078: suiteStorage = MIDletSuiteStorage.getMIDletSuiteStorage();
079: jarPath = suiteStorage.getMidletSuiteJarPath(suiteId);
080:
081: if (jarPath == null) {
082: exit(false);
083: return;
084: }
085: createProgressForm();
086: new Thread(new BackgroundVerifier(this , jarPath)).start();
087: }
088:
089: /**
090: * Exit the SuiteVerifier with the status supplied.
091: * It will perform any remaining cleanup and call notifyDestroyed.
092: * @param status <code>true</code> if the install was a success,
093: * <code>false</code> otherwise.
094: */
095: void exit(boolean status) {
096: /* TBD: Handle the status */
097: notifyDestroyed();
098: }
099:
100: /**
101: * Start.
102: */
103: public void startApp() {
104: }
105:
106: /**
107: * Pause; there are no resources that need to be released.
108: */
109: public void pauseApp() {
110: }
111:
112: /**
113: * Destroy cleans up.
114: *
115: * @param unconditional is ignored; this object always
116: * destroys itself when requested.
117: */
118: public void destroyApp(boolean unconditional) {
119: }
120:
121: /**
122: * Alert the user that an action was successful.
123: *
124: * @param successMessage message to display to user
125: */
126: private void displaySuccessMessage(String successMessage) {
127: Image icon;
128: Alert successAlert;
129: icon = GraphicalInstaller
130: .getImageFromInternalStorage("_dukeok8");
131:
132: successAlert = new Alert(null, successMessage, icon, null);
133: successAlert.setTimeout(GraphicalInstaller.ALERT_TIMEOUT);
134: // Provide a listener to disable the advance-to-next-displayable
135: // feature of Alert.
136: successAlert.setCommandListener(new CommandListener() {
137: public void commandAction(Command c, Displayable d) {
138: }
139: });
140: display.setCurrent(successAlert);
141: }
142:
143: /**
144: * Create main form for suite classes verification
145: * @return Created form instance
146: */
147: private Form createProgressForm() {
148:
149: progressForm = new Form(null);
150: progressForm.setTitle(Resource
151: .getString(ResourceConstants.AMS_CLASS_VERIFIER_TITLE));
152: Gauge progressGauge = new Gauge(
153: Resource
154: .getString(ResourceConstants.AMS_CLASS_VERIFIER_GAUGE_LABEL),
155: false, Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING);
156:
157: progressGaugeIndex = progressForm.append(progressGauge);
158: backCommand = new Command(Resource
159: .getString(ResourceConstants.BACK), Command.BACK, 1);
160: progressForm.addCommand(backCommand);
161: progressForm.setCommandListener(this );
162: display.setCurrent(progressForm);
163: return progressForm;
164: }
165:
166: /**
167: *
168: * @param command
169: * @param displayable
170: */
171: public void commandAction(Command command, Displayable displayable) {
172: if (command == backCommand) {
173: destroyApp(false);
174: notifyDestroyed();
175: } else if (command == Alert.DISMISS_COMMAND) {
176: // goto back to the manager midlet
177: exit(false);
178: }
179: }
180:
181: /**
182: * Display a warning to the user, with a done command.
183: *
184: * @param title warning form's title
185: * @param message warning message
186: */
187: private void displayWarning(String title, String message) {
188: Alert a = new Alert(title, message, null, AlertType.WARNING);
189: a.setTimeout(Alert.FOREVER);
190: a.setCommandListener(this );
191: display.setCurrent(a);
192: }
193:
194: /**
195: * Store hash value of the suite JAR after all classes
196: * in the package are successfully verified
197: */
198: private void storeSuiteHash() {
199: try {
200: // Evaluate suite hash value and store it
201: byte[] verifyHash = MIDletSuiteVerifier.getJarHash(jarPath);
202: suiteStorage.storeSuiteVerifyHash(suiteId, verifyHash);
203: } catch (IOException ioe) {
204: displayWarning(
205: Resource
206: .getString(ResourceConstants.AMS_CLASS_VERIFIER_WARNING),
207: Resource
208: .getString(ResourceConstants.AMS_CLASS_VERIFIER_CANT_STORE_HASH));
209: }
210: }
211:
212: /** A class to verify all classes of a JAR in a background thread. */
213: private class BackgroundVerifier implements Runnable {
214: /** Size of the verification portion */
215: final static int CHUNK_SIZE = 10240;
216:
217: /** Parent application. */
218: private SuiteVerifier parent;
219: /** JAR path. */
220: private String jarPath;
221:
222: /**
223: * Construct a BackgroundVerifier.
224: *
225: * @param theParent parent of this object
226: * @param theJarPath path of the JAR to be verified.
227: */
228: private BackgroundVerifier(SuiteVerifier theParent,
229: String theJarPath) {
230: parent = theParent;
231: jarPath = theJarPath;
232: }
233:
234: /** Verify in background all classes within a JAR */
235: public void run() {
236: int status = JVM.verifyJar(jarPath, CHUNK_SIZE);
237:
238: if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
239: Logging.report(Logging.WARNING, LogChannels.LC_AMS,
240: "JAR classes verification: " + jarPath + ", "
241: + status);
242: }
243:
244: if (parent.progressForm != null) {
245: // End the background thread of progress gauge.
246: Gauge progressGauge = (Gauge) parent.progressForm
247: .get(parent.progressGaugeIndex);
248: progressGauge.setValue(Gauge.CONTINUOUS_IDLE);
249: }
250:
251: if (status != JVM.STATUS_VERIFY_SUCCEEDED) {
252: parent
253: .displayWarning(
254: Resource
255: .getString(ResourceConstants.AMS_CLASS_VERIFIER_WARNING),
256: Resource
257: .getString(ResourceConstants.AMS_CLASS_VERIFIER_FAILURE));
258: } else {
259: parent.storeSuiteHash();
260: parent
261: .displaySuccessMessage(Resource
262: .getString(ResourceConstants.AMS_CLASS_VERIFIER_SUCCESS));
263: }
264:
265: parent.exit(true);
266: }
267: }
268: }
|