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.scriptutil;
028:
029: import javax.microedition.midlet.MIDlet;
030: import com.sun.midp.installer.*;
031: import com.sun.midp.configurator.Constants;
032:
033: /**
034: * A command-line installer. Allows to install midlet either from
035: * an http(s):// or from a file:// URL.
036: * <p>
037: * The MIDlet uses certain application properties as arguments: </p>
038: * <ol>
039: * <li>arg-0: currently must be "I" == install
040: * (for consistency with GraphicalInstaller)</li>
041: * <li>arg-1: URL of the midlet suite to install
042: * <li>arg-2: a storage ID where to save the suite's jar file
043: */
044: public class CommandLineInstaller extends MIDlet implements
045: InstallListener, Runnable {
046: /**
047: * Create and initialize the MIDlet.
048: */
049: public CommandLineInstaller() {
050: new Thread(this ).start();
051: }
052:
053: /**
054: * Start.
055: */
056: public void startApp() {
057: }
058:
059: /**
060: * Pause; there are no resources that need to be released.
061: */
062: public void pauseApp() {
063: }
064:
065: /**
066: * Destroy cleans up.
067: *
068: * @param unconditional is ignored; this object always
069: * destroys itself when requested.
070: */
071: public void destroyApp(boolean unconditional) {
072: }
073:
074: /** Prints a message about the midlet usage. */
075: private void showUsage() {
076: System.out.println("Usage: ./runMidlet internal "
077: + "CommandLineInstaller I <url> [storageId]");
078: }
079:
080: /** Installs a new MIDlet suite. */
081: public void run() {
082: Installer installer = null;
083: String installerClassName = null;
084: final String supportedUrlTypes[] = { "http", "HttpInstaller",
085: "https", "HttpInstaller", "file", "FileInstaller" };
086:
087: // parse the arguments
088: String arg0 = getAppProperty("arg-0");
089: if (arg0 == null || !"I".equals(arg0)) {
090: showUsage();
091: notifyDestroyed();
092: return;
093: }
094:
095: String url = getAppProperty("arg-1");
096: if (url == null) {
097: showUsage();
098: notifyDestroyed();
099: return;
100: }
101:
102: int storageId = Constants.INTERNAL_STORAGE_ID;
103: String strStorageId = getAppProperty("arg-2");
104: if (strStorageId != null) {
105: try {
106: storageId = Integer.parseInt(strStorageId);
107: } catch (NumberFormatException nfe) {
108: // Intentionally ignored
109: }
110: }
111:
112: // If a scheme is omitted, handle the url
113: // as a file on the local file system.
114: final String scheme = Installer.getUrlScheme(url, "file");
115:
116: for (int i = 0; i < supportedUrlTypes.length << 1; i++, i++) {
117: if (supportedUrlTypes[i].equals(scheme)) {
118: installerClassName = "com.sun.midp.installer."
119: + supportedUrlTypes[i + 1];
120: break;
121: }
122: }
123:
124: if (installerClassName != null) {
125: try {
126: installer = (Installer) Class.forName(
127: installerClassName).newInstance();
128: } catch (Throwable t) {
129: // Intentionally ignored: 'installer' is already null
130: }
131: }
132:
133: if (installer == null) {
134: final String errMsg = "'" + scheme
135: + "' URL type is not supported.";
136: System.out.println("ERROR: " + errMsg);
137: notifyDestroyed();
138: return;
139: }
140:
141: // install the suite
142: int lastInstalledMIDletId;
143: int len = url.length();
144: boolean jarOnly = (len >= 4 && ".jar".equalsIgnoreCase(url
145: .substring(len - 4, len)));
146:
147: try {
148: if (jarOnly) {
149: lastInstalledMIDletId = installer.installJar(url, null,
150: storageId, false, false, this );
151: } else {
152: lastInstalledMIDletId = installer.installJad(url,
153: storageId, false, false, this );
154: }
155:
156: System.out
157: .println("The suite was succesfully installed, ID: "
158: + lastInstalledMIDletId);
159: } catch (Throwable t) {
160: System.err.println("Error installing the suite: "
161: + t.getMessage());
162: t.printStackTrace();
163: }
164:
165: notifyDestroyed();
166: }
167:
168: // Implementation of the InstallListener interface.
169: // This implementation responds "yes" for all questions
170: // to proceed with the installation silently.
171:
172: /**
173: * Called with the current state of the install so the user can be
174: * asked to override the warning. To get the warning from the state
175: * call {@link InstallState#getLastException()}. If false is returned,
176: * the last exception in the state will be thrown and
177: * {@link Installer#wasStopped()} will return true if called.
178: *
179: * @param state current state of the install.
180: *
181: * @return true if the user wants to continue, false to stop the install
182: */
183: public boolean warnUser(InstallState state) {
184: return true;
185: }
186:
187: /**
188: * Called with the current state of the install so the user can be
189: * asked to confirm the jar download.
190: * If false is returned, the an I/O exception thrown and
191: * {@link Installer#wasStopped()} will return true if called.
192: *
193: * @param state current state of the install.
194: *
195: * @return true if the user wants to continue, false to stop the install
196: */
197: public boolean confirmJarDownload(InstallState state) {
198: return true;
199: }
200:
201: /**
202: * Called with the current status of the install. See
203: * {@link Installer} for the status codes.
204: *
205: * @param status current status of the install.
206: * @param state current state of the install.
207: */
208: public void updateStatus(int status, InstallState state) {
209: }
210:
211: /**
212: * Called with the current state of the install so the user can be
213: * asked to confirm if the RMS data should be kept for new version of
214: * an updated suite.
215: * If false is returned, the an I/O exception thrown and
216: * {@link Installer#wasStopped()} will return true if called.
217: *
218: * @param state current state of the install.
219: *
220: * @return true if the user wants to keep the RMS data for the next suite
221: */
222: public boolean keepRMS(InstallState state) {
223: return true;
224: }
225:
226: /**
227: * Called with the current state of the install so the user can be
228: * asked to confirm the authentication path.
229: * If false is returned, the an I/O exception thrown and
230: * {@link Installer#wasStopped()} will return true if called.
231: *
232: * @param state current state of the install.
233: *
234: * @return true if the user wants to continue, false to stop the install
235: */
236: public boolean confirmAuthPath(InstallState state) {
237: return true;
238: }
239: }
|