0001: /*
0002: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0004: *
0005: * This program is free software; you can redistribute it and/or
0006: * modify it under the terms of the GNU General Public License version
0007: * 2 only, as published by the Free Software Foundation.
0008: *
0009: * This program is distributed in the hope that it will be useful, but
0010: * WITHOUT ANY WARRANTY; without even the implied warranty of
0011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0012: * General Public License version 2 for more details (a copy is
0013: * included at /legal/license.txt).
0014: *
0015: * You should have received a copy of the GNU General Public License
0016: * version 2 along with this work; if not, write to the Free Software
0017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0018: * 02110-1301 USA
0019: *
0020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0021: * Clara, CA 95054 or visit www.sun.com if you need additional
0022: * information or have any questions.
0023: */
0024:
0025: package com.sun.jumpimpl.module.installer;
0026:
0027: import com.sun.jump.common.JUMPAppModel;
0028: import com.sun.jump.common.JUMPApplication;
0029: import com.sun.jump.common.JUMPContent;
0030: import com.sun.jump.executive.JUMPExecutive;
0031: import com.sun.jump.module.JUMPModuleFactory;
0032: import com.sun.jump.module.download.JUMPDownloadDescriptor;
0033: import com.sun.jump.module.download.JUMPDownloadDestination;
0034: import com.sun.jump.module.download.JUMPDownloadException;
0035: import com.sun.jump.module.download.JUMPDownloadModule;
0036: import com.sun.jump.module.download.JUMPDownloadModuleFactory;
0037: import com.sun.jump.module.download.JUMPDownloader;
0038: import com.sun.jump.module.installer.JUMPInstallerModule;
0039: import com.sun.jump.module.installer.JUMPInstallerModuleFactory;
0040: import com.sun.jumpimpl.module.download.DownloadDestinationImpl;
0041: import com.sun.jumpimpl.module.download.OTADiscovery;
0042: import java.io.File;
0043: import java.net.MalformedURLException;
0044: import java.net.URISyntaxException;
0045: import java.net.URL;
0046: import java.util.HashMap;
0047: import java.util.Hashtable;
0048: import java.util.Iterator;
0049: import java.util.Properties;
0050: import java.util.Vector;
0051:
0052: /**
0053: * This class is an installation tool for downloading,
0054: * installing, uninstalling, and listing content in the
0055: * content store application repository.
0056: *
0057: * This class should be routinely modified with more
0058: * features as development continues.
0059: *
0060: * The current supported commands are:
0061: * list, info, install, install_all, uninstall, uninstall_all
0062: *
0063: * The commands install and uninstall will provide the user with an interactive
0064: * way to choose files to be installed or uninstalled. The command install_all
0065: * and uninstall_all will install or uninstall all content without interactive
0066: * with the user.
0067: *
0068: * Usage:
0069: * <cvm> <system properties> -cp <classpath> com.sun.jumpimpl.module.installer.JUMPInstallerTool -ProvisioningServerURL <url of provisioning server> <options> -command <command>
0070: * <system properties> is optional, but it should be known that contentstore.root
0071: * can be overridden here if desired.
0072: * For example, -Dcontentstore.root=<repository dir> can be specified
0073: * <command> can currently be list, info, install, install_all, uninstall, and uninstall_all
0074: * <options>
0075: * -verbose: print debugging messages
0076: *
0077: * Ex:
0078: * cvm -cp $JUMP_JARS com.sun.jumpimpl.module.installer.JUMPInstallerTool -command list
0079: * cvm -Dcontentstore.root=data2 -cp $JUMP_JARS com.sun.jumpimpl.module.installer.JUMPInstallerTool -command install
0080: * cvm -cp $JUMP_JARS com.sun.jumpimpl.module.installer.JUMPInstallerTool -command uninstall
0081: * cvm -cp $JUMP_JARS com.sun.jumpimpl.module.installer.JUMPInstallerTool -verbose -command install_all
0082: * cvm -cp $JUMP_JARS com.sun.jumpimpl.module.installer.JUMPInstallerTool -command uninstall_all
0083: *
0084: */
0085: public class JUMPInstallerTool {
0086:
0087: /**
0088: * xlet installer module object
0089: */
0090: protected JUMPInstallerModule xletInstaller = null;
0091: /**
0092: * midlet installer module object
0093: */
0094: protected JUMPInstallerModule midletInstaller = null;
0095: /**
0096: * main installer module object
0097: */
0098: protected JUMPInstallerModule mainInstaller = null;
0099: /**
0100: * holds download module object
0101: */
0102: protected JUMPDownloadModule downloadModule = null;
0103: /**
0104: * URL used for Provisioning Server location
0105: */
0106: protected String ProvisioningServer = null;
0107: /**
0108: * The current command to be run
0109: */
0110: protected String Command = null;
0111: /**
0112: * Sub-values for the current command to be run
0113: */
0114: protected String Value = null;
0115: /**
0116: * Whether or not to print debug messages
0117: */
0118: protected boolean Verbose = false;
0119: /**
0120: * URL containing the content to be installed.
0121: */
0122: protected String ContentURL = null;
0123: /**
0124: * URI of the descriptor file of the content to be installed
0125: */
0126: protected String DescriptorURI = null;
0127: /**
0128: * The protocol of the content. The value should be either:
0129: * ota/midp or ota/oma
0130: */
0131: protected String Protocol = null;
0132: /**
0133: * The application type of an installed content
0134: */
0135: protected String Type = null;
0136: /**
0137: * The id of an installed content.
0138: */
0139: protected String Id = null;
0140: /**
0141: * The current root of content store where applications are located
0142: */
0143: private String repository = null;
0144: /**
0145: * The property name holding the root of content store
0146: */
0147: private static final String repositoryProperty = "contentstore.root";
0148:
0149: private Hashtable parseArgs(String args[]) {
0150: if (args == null) {
0151: return null;
0152: }
0153: Hashtable argTable = new Hashtable();
0154: String arg = null;
0155:
0156: // The options -ContentURL, -DescriptorURI, and -Protocol are not
0157: // yet functional yet as our download implementation's createDescriptor
0158: // methods assume an http connection.
0159: for (int i = 0; i < args.length; i++) {
0160: if (args[i].equals("-ProvisioningServerURL")) {
0161: arg = args[++i];
0162: argTable.put("ProvisioningServerURL", arg);
0163: } else if (args[i].equals("-command")) {
0164: arg = args[++i];
0165: argTable.put("Command", arg);
0166: } else if (args[i].equals("-verbose")) {
0167: System.setProperty("installer.verbose", "true");
0168: argTable.put("Verbose", "true");
0169: } else if (args[i].equals("-ContentURL")) {
0170: arg = args[++i];
0171: argTable.put("ContentURL", arg);
0172: } else if (args[i].equals("-DescriptorURI")) {
0173: arg = args[++i];
0174: argTable.put("DescriptorURI", arg);
0175: } else if (args[i].equals("-Protocol")) {
0176: arg = args[++i];
0177: argTable.put("Protocol", arg);
0178: } else if (args[i].equals("-id")) {
0179: arg = args[++i];
0180: argTable.put("Id", arg);
0181: } else if (args[i].equals("-type")) {
0182: arg = args[++i];
0183: argTable.put("Type", arg);
0184: }
0185: }
0186: return argTable;
0187: }
0188:
0189: /**
0190: * Creates a new instance of JUMPInstallerTool
0191: * @param args arguments for the tool
0192: */
0193: public JUMPInstallerTool(String[] args) {
0194: Hashtable hash = parseArgs(args);
0195: this .Command = (String) hash.get("Command");
0196: String verbose = (String) hash.get("Verbose");
0197: if (verbose != null && verbose.equals("true")) {
0198: this .Verbose = true;
0199: }
0200:
0201: this .ProvisioningServer = (String) hash
0202: .get("ProvisioningServerURL");
0203:
0204: // The three lines of code below, along with usage of the fields,
0205: // is for a future case where the tool will allow local installations.
0206: this .ContentURL = (String) hash.get("ContentURL");
0207: this .DescriptorURI = (String) hash.get("DescriptorURI");
0208: this .Protocol = (String) hash.get("Protocol");
0209: this .Type = (String) hash.get("Type");
0210: this .Id = (String) hash.get("Id");
0211:
0212: trace("");
0213: trace("=============================================");
0214: trace("JUMPInstallerTool Settings");
0215: trace("--------------------------");
0216: trace("");
0217: trace(" Command: " + Command);
0218: trace("App Server: " + ProvisioningServer);
0219: trace(" ID: " + Id);
0220: trace(" Type: " + Type);
0221: trace("=============================================");
0222: trace("");
0223:
0224: if (!setup()) {
0225: System.exit(-1);
0226: }
0227: ;
0228:
0229: if (Command != null) {
0230: doCommand();
0231: }
0232: }
0233:
0234: private void usage() {
0235: System.out.println("Usage:");
0236: System.out
0237: .println(" <cvm> <system properties> -cp <classpath> com.sun.jumpimpl.module.installer.JUMPInstallerTool <options> -command <command>");
0238: System.out
0239: .println("Available commands that can be used are: list, install, install_all, uninstall, and uninstall_all.");
0240: System.out.println("Available options: -verbose");
0241: System.out.println("");
0242: System.out.println("Ex:");
0243: System.out
0244: .println(" cvm -cp $JUMP_JARS com.sun.jumpimpl.module.installer.JUMPInstallerTool -verbose -command list");
0245: System.out.println("");
0246: }
0247:
0248: private void trace(String str) {
0249: if (this .Verbose) {
0250: System.out.println(str);
0251: }
0252: }
0253:
0254: private boolean setup() {
0255:
0256: repository = System.getProperty(repositoryProperty);
0257: if (repository != null) {
0258: // test setup, make a repository root
0259: File file = new File(repository);
0260: if (!file.exists()) {
0261: System.out.println("ERROR: " + repository
0262: + " directory not found.");
0263: return false;
0264: }
0265: }
0266:
0267: if (JUMPExecutive.getInstance() == null) {
0268: JUMPModuleFactory factory = null;
0269: factory = new com.sun.jumpimpl.module.installer.InstallerFactoryImpl();
0270: factory.load(com.sun.jumpimpl.process.JUMPModulesConfig
0271: .getProperties());
0272: factory = new com.sun.jumpimpl.module.contentstore.StoreFactoryImpl();
0273: factory.load(com.sun.jumpimpl.process.JUMPModulesConfig
0274: .getProperties());
0275: factory = new com.sun.jumpimpl.module.download.DownloadModuleFactoryImpl();
0276: factory.load(com.sun.jumpimpl.process.JUMPModulesConfig
0277: .getProperties());
0278: }
0279:
0280: return true;
0281: }
0282:
0283: private JUMPInstallerModule createInstaller(JUMPAppModel type) {
0284:
0285: JUMPInstallerModule module = null;
0286:
0287: if (type == JUMPAppModel.MAIN) {
0288: module = JUMPInstallerModuleFactory.getInstance()
0289: .getModule(JUMPAppModel.MAIN);
0290: } else if (type == JUMPAppModel.XLET) {
0291: module = JUMPInstallerModuleFactory.getInstance()
0292: .getModule(JUMPAppModel.XLET);
0293: } else if (type == JUMPAppModel.MIDLET) {
0294: module = JUMPInstallerModuleFactory.getInstance()
0295: .getModule(JUMPAppModel.MIDLET);
0296: }
0297:
0298: if (module == null) {
0299: return null;
0300: }
0301:
0302: return module;
0303: }
0304:
0305: private void doCommand() {
0306: if (Command.equals("install")) {
0307: if (DescriptorURI != null) {
0308: doInstall(DescriptorURI);
0309: } else {
0310: doInstall(ProvisioningServer, true);
0311: }
0312: } else if (Command.equals("install_all")) {
0313: doInstall(ProvisioningServer, false);
0314: } else if (Command.equals("list")) {
0315: doList();
0316: } else if (Command.equals("uninstall")) {
0317: if (Id != null && Type != null) {
0318: doUninstall(JUMPAppModel.fromName(Type), Integer
0319: .parseInt(Id));
0320: } else {
0321: doUninstall(true);
0322: }
0323: } else if (Command.equals("uninstall_all")) {
0324: doUninstall(false);
0325: } else if (Command.equals("info")) {
0326: doInfo();
0327: }
0328: }
0329:
0330: private void error() {
0331: System.out.println("ERROR: Could not install.");
0332: if (!this .Verbose) {
0333: System.out
0334: .println("==> Please run with -verbose for more information.");
0335: }
0336: }
0337:
0338: /**
0339: * Print out information pertaining to each application in a list.
0340: */
0341: public void doInfo() {
0342: System.out.println("");
0343: System.out.println("---------------------------------");
0344: System.out.println("Applications Within Content Store");
0345: System.out.println("---------------------------------");
0346: System.out.println("");
0347:
0348: JUMPInstallerModule installers[] = JUMPInstallerModuleFactory
0349: .getInstance().getAllInstallers();
0350:
0351: int numApps = 0;
0352:
0353: for (int i = 0; i < installers.length; i++) {
0354:
0355: JUMPContent[] content = installers[i].getInstalled();
0356: if (content != null) {
0357: for (int j = 0; j < content.length; j++) {
0358: numApps++;
0359: JUMPApplication app = (JUMPApplication) content[j];
0360: System.out.println("App #" + numApps + ": "
0361: + app.getTitle());
0362: JUMPAppModel model = app.getAppType();
0363: if (model == JUMPAppModel.XLET) {
0364: XLETApplication xlet = (XLETApplication) app;
0365: System.out.println(" Bundle: "
0366: + xlet.getBundle());
0367: System.out.println(" Jar: "
0368: + xlet.getClasspath());
0369: System.out.println("Install ID: "
0370: + xlet.getId());
0371: URL iconPath = xlet.getIconPath();
0372: if (iconPath == null) {
0373: System.out.println(" Icon: <none>");
0374: } else {
0375: System.out.println(" Icon: "
0376: + iconPath.getFile());
0377: }
0378: System.out.println(" Model: "
0379: + JUMPAppModel.XLET.toString());
0380: } else if (model == JUMPAppModel.MAIN) {
0381: MAINApplication main = (MAINApplication) app;
0382: System.out.println(" Bundle: "
0383: + main.getBundle());
0384: System.out.println(" Jar: "
0385: + main.getClasspath());
0386: System.out.println("Install ID: "
0387: + main.getId());
0388: URL iconPath = main.getIconPath();
0389: if (iconPath == null) {
0390: System.out.println(" Icon: <none>");
0391: } else {
0392: System.out.println(" Icon: "
0393: + iconPath.getFile());
0394: }
0395: System.out.println(" Model: "
0396: + JUMPAppModel.MAIN.toString());
0397: } else if (model == JUMPAppModel.MIDLET) {
0398: System.out
0399: .println(" Suite ID: "
0400: + app
0401: .getProperty("MIDletApplication_suiteid"));
0402: System.out
0403: .println("Install ID: " + app.getId());
0404: URL iconPath = app.getIconPath();
0405: if (iconPath == null) {
0406: System.out.println(" Icon: <none>");
0407: } else {
0408: if (iconPath.getProtocol().equals("jar")) {
0409: System.out.println(" Icon: jar:"
0410: + iconPath.getFile());
0411: } else {
0412: System.out.println(" Icon: "
0413: + iconPath.getFile());
0414: }
0415: }
0416: System.out.println(" Model: "
0417: + JUMPAppModel.MIDLET.toString());
0418: }
0419:
0420: System.out.println("");
0421: }
0422: }
0423: }
0424:
0425: System.out.println("");
0426: }
0427:
0428: private String getProtocol(String url) {
0429: if (url.endsWith(".jad")) {
0430: return JUMPDownloadModuleFactory.PROTOCOL_MIDP_OTA;
0431: } else if (url.endsWith(".dd")) {
0432: return JUMPDownloadModuleFactory.PROTOCOL_OMA_OTA;
0433: } else {
0434: return null;
0435: }
0436: }
0437:
0438: /**
0439: * Install the content described by the specified content descriptor file.
0440: * The content will be automatically downloaded before being installed.
0441: *
0442: * @param descriptorFileUrl A URL to a content desciptor file.
0443: * @return the installed content
0444: */
0445: public JUMPContent[] doInstall(String descriptorFileUrl) {
0446: return doInstall("<no title>", descriptorFileUrl);
0447: }
0448:
0449: /**
0450: * Install the content described by the specified content descriptor files.
0451: * The content will be automatically downloaded before being installed.
0452: *
0453: * @param descriptorFileUrl A URL to a content desciptor file.
0454: * @return the installed content
0455: */
0456: public JUMPContent[] doInstall(String descriptorFileUrl[]) {
0457: Vector contentVector = new Vector();
0458: for (int i = 0; i < descriptorFileUrl.length; i++) {
0459: JUMPContent content[] = doInstall("<no title>",
0460: descriptorFileUrl[i]);
0461: for (int j = 0; j < content.length; j++) {
0462: contentVector.add(content[j]);
0463: }
0464: }
0465: return (JUMPContent[]) contentVector
0466: .toArray(new JUMPContent[] {});
0467: }
0468:
0469: /**
0470: * Install content given a list of names and URIs
0471: * to content descriptor files.
0472: * @param downloadNames The title of the content.
0473: * The index of the array for this value
0474: * relates to the same index in teh
0475: * array for downloadURIs.
0476: * @param downloadURIs The URIs to the content descriptor
0477: * files.
0478: *
0479: * The index of the array for this value
0480: * relates to the same index in teh
0481: * array for downloadNames.
0482: * @return the installed content
0483: */
0484: public JUMPContent[] doInstall(String downloadNames[],
0485: String downloadURIs[]) {
0486: DownloadTool downloadTool = new DownloadTool();
0487: downloadTool.startTool(downloadNames, downloadURIs);
0488: URL contentURLs[] = downloadTool.getURLs();
0489: JUMPDownloadDescriptor[] descriptors = downloadTool
0490: .getDescriptors();
0491: JUMPContent[] content = install(contentURLs, descriptors);
0492: cleanup(contentURLs, descriptors);
0493: return content;
0494: }
0495:
0496: /**
0497: * Install content given a name and a URI
0498: * to a content descriptor file.
0499: * @param downloadName The name of the content
0500: * @param downloadURI The URI to the content descriptor file
0501: * @return the installed content
0502: */
0503: public JUMPContent[] doInstall(String downloadName,
0504: String downloadURI) {
0505: DownloadTool downloadTool = new DownloadTool();
0506: downloadTool.startTool(downloadName, downloadURI);
0507: URL contentURLs[] = downloadTool.getURLs();
0508: JUMPDownloadDescriptor[] descriptors = downloadTool
0509: .getDescriptors();
0510: JUMPContent[] content = install(contentURLs, descriptors);
0511: cleanup(contentURLs, descriptors);
0512: return content;
0513: }
0514:
0515: /**
0516: * Given a provisioning server URL, install content
0517: * @param provisioningServerURL The URL to a provisioning server
0518: * @param userInteractive When true, the user chooses an
0519: * application to install among a list
0520: * of available content.
0521: *
0522: * When false, all available content is
0523: * automatically installed.
0524: * @return the installed content
0525: */
0526: public JUMPContent[] doInstall(String provisioningServerURL,
0527: boolean userInteractive) {
0528: DownloadTool downloadTool = new DownloadTool(
0529: provisioningServerURL);
0530: downloadTool.startTool(userInteractive);
0531: URL contentURLs[] = downloadTool.getURLs();
0532: JUMPDownloadDescriptor[] descriptors = downloadTool
0533: .getDescriptors();
0534: JUMPContent[] content = install(contentURLs, descriptors);
0535: cleanup(contentURLs, descriptors);
0536: return content;
0537: }
0538:
0539: private void cleanup(URL urls[],
0540: JUMPDownloadDescriptor[] descriptors) {
0541: // Remove locally downloaded content, i.e. tmp local jar files
0542: for (int i = 0; i < urls.length; i++) {
0543: File contentFile = new File(urls[i].getFile());
0544: if (contentFile.exists()) {
0545: System.out
0546: .println("*** Cleaning up tmp download content: "
0547: + contentFile.toString());
0548: contentFile.delete();
0549: }
0550: }
0551: // Remove locally downloaded jad files
0552: for (int i = 0; i < descriptors.length; i++) {
0553: Properties prop = descriptors[i].getApplications()[0];
0554: String localJadFile = prop
0555: .getProperty("JUMPApplication_localJadUrl");
0556: if (localJadFile == null) {
0557: continue;
0558: }
0559: File localJad = new File(localJadFile);
0560: if (localJad.exists()) {
0561: System.out.println("*** Cleaning up tmp jad: "
0562: + localJad.toString());
0563: localJad.delete();
0564: }
0565: }
0566: }
0567:
0568: /**
0569: * Uninstall content given the content type and
0570: * installed application id.
0571: * @param model the content type, i.e.,
0572: * midlet, xlet, or main
0573: * @param id the installed application id
0574: */
0575: public void doUninstall(JUMPAppModel model, int id) {
0576: JUMPInstallerModule installer = createInstaller(model);
0577: JUMPContent content[] = installer.getInstalled();
0578: int i = 0;
0579: for (i = 0; i < content.length; i++) {
0580: JUMPApplication app = (JUMPApplication) content[i];
0581: if (app.getId() == id) {
0582: break;
0583: }
0584: }
0585: if (i < content.length) {
0586: uninstall((JUMPApplication) content[i]);
0587: }
0588: }
0589:
0590: /**
0591: * Uninstall content
0592: * @param app the application to uninstall
0593: */
0594: public void doUninstall(JUMPApplication app) {
0595: uninstall(app);
0596: }
0597:
0598: /**
0599: * Uninstall content
0600: * @param apps the content to uninstall
0601: */
0602: public void doUninstall(JUMPApplication apps[]) {
0603: uninstall(apps);
0604: }
0605:
0606: /**
0607: * Uninstall content
0608: * @param userInteractive if true, the user chooses an application
0609: * among a list of all installed content
0610: * to uninstall.
0611: *
0612: * if false, all installed content in
0613: * uninstalled.
0614: */
0615: public void doUninstall(boolean userInteractive) {
0616: if (userInteractive) {
0617: userInteractiveUninstall();
0618: } else {
0619: nonInteractiveUninstall();
0620: }
0621: }
0622:
0623: private void uninstall(JUMPApplication app) {
0624: JUMPApplication apps[] = new JUMPApplication[1];
0625: apps[0] = app;
0626: uninstall(apps);
0627: }
0628:
0629: private void uninstall(JUMPApplication[] apps) {
0630: if (apps == null) {
0631: trace("ERROR: No apps specified to uninstall.");
0632: error();
0633: return;
0634: }
0635:
0636: for (int i = 0; i < apps.length; i++) {
0637: System.out.println("");
0638: System.out.println("==> Uninstalling: "
0639: + apps[i].getTitle());
0640: if (apps[i] == null) {
0641: System.out.println("ERROR: " + apps[i].getTitle()
0642: + " not found in content store.");
0643: } else {
0644: JUMPInstallerModule installer = null;
0645: if (apps[i].getAppType() == JUMPAppModel.XLET) {
0646: installer = createInstaller(JUMPAppModel.XLET);
0647: } else if (apps[i].getAppType() == JUMPAppModel.MAIN) {
0648: installer = createInstaller(JUMPAppModel.MAIN);
0649: } else if (apps[i].getAppType() == JUMPAppModel.MIDLET) {
0650: installer = createInstaller(JUMPAppModel.MIDLET);
0651: }
0652: installer.uninstall(apps[i]);
0653: }
0654: System.out.println("==> Finished Uninstalling: "
0655: + apps[i].getTitle());
0656: System.out.println("");
0657: }
0658: }
0659:
0660: private void userInteractiveUninstall() {
0661: System.setProperty("jump.installer.interactive", "true");
0662:
0663: JUMPInstallerModule installers[] = JUMPInstallerModuleFactory
0664: .getInstance().getAllInstallers();
0665:
0666: Vector appsVector = new Vector();
0667:
0668: // Get all of the apps
0669: for (int i = 0, totalApps = 0; i < installers.length; i++) {
0670: JUMPContent[] content = installers[i].getInstalled();
0671: if (content != null) {
0672: for (int j = 0; j < content.length; j++) {
0673: appsVector.add(totalApps, content[j]);
0674: totalApps++;
0675: }
0676: }
0677: }
0678:
0679: if (appsVector.size() == 0) {
0680: System.out
0681: .println("No applications are installed in the content store.");
0682: return;
0683: }
0684:
0685: // Show what is available and read input for a choice.
0686: System.out.println("uninstall choices: ");
0687: Object apps[] = appsVector.toArray();
0688: for (int i = 0; i < apps.length; i++) {
0689: System.out.println("(" + i + "): "
0690: + ((JUMPApplication) apps[i]).getTitle());
0691: }
0692:
0693: String message = "Enter choice (-1 to exit) [-1]: ";
0694: String choice = Utilities.promptUser(message);
0695: int chosenUninstall = Integer.parseInt(choice);
0696:
0697: System.out.println(chosenUninstall);
0698:
0699: JUMPApplication app = (JUMPApplication) appsVector
0700: .get(chosenUninstall);
0701:
0702: JUMPApplication[] chosenApps = new JUMPApplication[1];
0703: chosenApps[0] = app;
0704: uninstall(chosenApps);
0705: }
0706:
0707: private void nonInteractiveUninstall() {
0708: System.setProperty("jump.installer.interactive", "false");
0709:
0710: JUMPInstallerModule installers[] = JUMPInstallerModuleFactory
0711: .getInstance().getAllInstallers();
0712:
0713: for (int i = 0; i < installers.length; i++) {
0714: JUMPContent[] content = installers[i].getInstalled();
0715: while (content != null && content.length > 0) {
0716: if (content[0] != null) {
0717: System.out.println("");
0718: System.out
0719: .println("==> Uninstalling: "
0720: + ((JUMPApplication) content[0])
0721: .getTitle());
0722: installers[i].uninstall(content[0]);
0723: System.out
0724: .println("==> Finished Uninstalling: "
0725: + ((JUMPApplication) content[0])
0726: .getTitle());
0727: System.out.println("");
0728: }
0729: content = installers[i].getInstalled();
0730: }
0731: }
0732: }
0733:
0734: /**
0735: * Install JUMP content
0736: * url - URL of content to install, must be a file protocol URL
0737: * desc - download descriptor object
0738: */
0739: private JUMPContent[] install(URL url[],
0740: JUMPDownloadDescriptor desc[]) {
0741: Vector contentVector = new Vector();
0742:
0743: if (url.length != desc.length) {
0744: System.err
0745: .println("ERROR: Number of URLs to install does not equal the number of given download descriptors.");
0746: error();
0747: return null;
0748: }
0749: for (int i = 0; i < url.length; i++) {
0750: if (desc != null && url != null) {
0751: if (!url[i].getProtocol().equals("file")) {
0752: System.out.println("ERROR: Invalid protocol for:"
0753: + url[i].toString());
0754: continue;
0755: }
0756: System.out.println("");
0757: System.out.println("==> Installing: "
0758: + desc[i].getName() + " from: "
0759: + url[i].toString());
0760: Properties apps[] = desc[i].getApplications();
0761: if (apps == null) {
0762: trace("ERROR: Could not install. Descriptor contains no information on application.");
0763: error();
0764: return null;
0765: }
0766: String appType = apps[0]
0767: .getProperty("JUMPApplication_appModel");
0768: JUMPInstallerModule installer = null;
0769: if (appType.equals("xlet")) {
0770: installer = createInstaller(JUMPAppModel.XLET);
0771: } else if (appType.equals("main")) {
0772: installer = createInstaller(JUMPAppModel.MAIN);
0773: } else if (appType.equals("midlet")) {
0774: installer = createInstaller(JUMPAppModel.MIDLET);
0775: } else {
0776: trace("ERROR: Unknown application type: " + appType);
0777: error();
0778: return null;
0779: }
0780: JUMPContent installedApps[] = installer.install(url[i],
0781: desc[i]);
0782: if (installedApps != null) {
0783: // Print installed apps.
0784: for (int j = 0; j < installedApps.length; j++) {
0785: System.out.println("Application Installed: "
0786: + ((JUMPApplication) installedApps[j])
0787: .getTitle());
0788: contentVector.add(installedApps[j]);
0789: }
0790: } else {
0791: System.out
0792: .println("ERROR: No applications were installed for: "
0793: + desc[i].getName() + ".");
0794: error();
0795: }
0796: System.out.println("==> Finished Installing: "
0797: + desc[i].getName());
0798: System.out.println("");
0799: }
0800: }
0801:
0802: return (JUMPContent[]) contentVector
0803: .toArray(new JUMPContent[] {});
0804: }
0805:
0806: /**
0807: * Print out a list of all installed content.
0808: */
0809: public void doList() {
0810: System.out.println("");
0811: System.out.println("---------------------------------");
0812: System.out.println("Applications Within Content Store");
0813: System.out.println("---------------------------------");
0814: System.out.println("");
0815:
0816: JUMPInstallerModule installers[] = JUMPInstallerModuleFactory
0817: .getInstance().getAllInstallers();
0818:
0819: int numApps = 0;
0820:
0821: for (int i = 0; i < installers.length; i++) {
0822:
0823: JUMPContent[] content = installers[i].getInstalled();
0824: if (content != null) {
0825: for (int j = 0; j < content.length; j++) {
0826: numApps++;
0827: System.out
0828: .println("App #"
0829: + numApps
0830: + ": "
0831: + ((JUMPApplication) content[j])
0832: .getTitle());
0833: }
0834: }
0835: }
0836:
0837: System.out.println("");
0838: }
0839:
0840: class DownloadTool {
0841:
0842: private String provisioningServerURL = null;
0843:
0844: // Values only used for a JSR 124 server
0845: private final String omaSubDirectory = "oma";
0846: private final String midpSubDirectory = "jam";
0847:
0848: private boolean downloadFinished = false;
0849: private boolean downloadAborted = false;
0850:
0851: String outputFile = null;
0852:
0853: byte[] buffer = null;
0854: int bufferIndex = 0;
0855:
0856: private Vector descriptorVector = null;
0857: private Vector urlVector = null;
0858:
0859: private String downloadNames[] = null;
0860: private String downloadURIs[] = null;
0861:
0862: public DownloadTool() {
0863: setup();
0864: }
0865:
0866: public DownloadTool(String provisioningServerURL) {
0867: this .provisioningServerURL = provisioningServerURL;
0868: setup();
0869: }
0870:
0871: void setup() {
0872: descriptorVector = new Vector();
0873: urlVector = new Vector();
0874: }
0875:
0876: public URL[] getURLs() {
0877: return (URL[]) urlVector.toArray(new URL[] {});
0878: }
0879:
0880: public JUMPDownloadDescriptor[] getDescriptors() {
0881: return (JUMPDownloadDescriptor[]) descriptorVector
0882: .toArray(new JUMPDownloadDescriptor[] {});
0883: }
0884:
0885: public void startTool(String downloadName, String downloadURI) {
0886: String tmpDownloadNames[] = new String[1];
0887: String tmpDownloadURIs[] = new String[1];
0888: tmpDownloadNames[0] = downloadName;
0889: tmpDownloadURIs[0] = downloadURI;
0890: startTool(tmpDownloadNames, tmpDownloadURIs);
0891: }
0892:
0893: public void startTool(String downloadNames[],
0894: String downloadURIs[]) {
0895: this .downloadNames = downloadNames;
0896: this .downloadURIs = downloadURIs;
0897: nonInteractiveDownload(downloadURIs, downloadNames);
0898: }
0899:
0900: public void startTool(boolean userInteractive) {
0901: // Determine the discovery URL
0902: if (provisioningServerURL != null) {
0903: System.out.println("Using provisioning server URL at: "
0904: + provisioningServerURL);
0905: } else {
0906: System.out
0907: .println("A provisioning server url needs to be supplied.");
0908: System.out
0909: .println("Please run again with an value set to the -ProvisioningServerURL flag.");
0910: System.exit(0);
0911: }
0912:
0913: // Check if we're using a JSR 124 server
0914: if (provisioningServerURL.endsWith("ri-test")) {
0915:
0916: HashMap applistOMA = new OTADiscovery()
0917: .discover(provisioningServerURL + "/"
0918: + omaSubDirectory);
0919: HashMap applistMIDP = new OTADiscovery()
0920: .discover(provisioningServerURL + "/"
0921: + midpSubDirectory);
0922:
0923: downloadURIs = new String[applistOMA.size()
0924: + applistMIDP.size()];
0925: downloadNames = new String[applistOMA.size()
0926: + applistMIDP.size()];
0927:
0928: int i = 0;
0929: for (Iterator e = applistOMA.keySet().iterator(); e
0930: .hasNext();) {
0931: String s = (String) e.next();
0932: downloadURIs[i] = s;
0933: downloadNames[i] = (String) applistOMA.get(s);
0934: i++;
0935: }
0936:
0937: for (Iterator e = applistMIDP.keySet().iterator(); e
0938: .hasNext();) {
0939: String s = (String) e.next();
0940: downloadURIs[i] = s;
0941: downloadNames[i] = (String) applistMIDP.get(s);
0942: i++;
0943: }
0944: } else {
0945: // we're using an apache-based server
0946: HashMap applist = new OTADiscovery()
0947: .discover(provisioningServerURL);
0948:
0949: downloadURIs = new String[applist.size()];
0950: downloadNames = new String[applist.size()];
0951:
0952: int i = 0;
0953: for (Iterator e = applist.keySet().iterator(); e
0954: .hasNext();) {
0955: String s = (String) e.next();
0956: downloadURIs[i] = s;
0957: downloadNames[i] = (String) applist.get(s);
0958: i++;
0959: }
0960: }
0961:
0962: if (userInteractive) {
0963: userInteractiveDownload(downloadURIs, downloadNames);
0964: } else {
0965: nonInteractiveDownload(downloadURIs, downloadNames);
0966: }
0967:
0968: }
0969:
0970: void nonInteractiveDownload(String[] downloadURIs,
0971: String[] downloadNames) {
0972: for (int i = 0; i < downloadURIs.length; i++) {
0973: trace("Downloading: " + downloadNames[i]);
0974: doDownload(downloadNames[i], downloadURIs[i]);
0975: }
0976: }
0977:
0978: void userInteractiveDownload(String[] downloadURIs,
0979: String[] downloadNames) {
0980:
0981: // Show what is available and read input for a choice.
0982: System.out.println("download choices: ");
0983: for (int i = 0; i < downloadNames.length; i++) {
0984: System.out.println("(" + i + "): " + downloadNames[i]);
0985: }
0986: String message = "Enter choice (-1 to exit) [-1]: ";
0987: String choice = Utilities.promptUser(message);
0988: System.out.println("--> choice: " + choice);
0989: int chosenDownload = Integer.parseInt(choice);
0990: System.out.println("--> chosenDownload: " + chosenDownload);
0991: // If no valid choice, quit
0992: if (chosenDownload < 0) {
0993: System.exit(0);
0994: }
0995:
0996: System.out.println(chosenDownload + ": "
0997: + downloadURIs[chosenDownload]);
0998: boolean rv = doDownload(downloadNames[chosenDownload],
0999: downloadURIs[chosenDownload]);
1000: }
1001:
1002: private boolean doDownload(String name, String uri) {
1003: // Initiate a download. We've specified ourselves
1004: // as the handler of the data.
1005: if (uri.endsWith(".dd")) {
1006: startDownload(name, uri,
1007: JUMPDownloadModuleFactory.PROTOCOL_OMA_OTA);
1008: } else if (uri.endsWith(".jad")) {
1009: startDownload(name, uri,
1010: JUMPDownloadModuleFactory.PROTOCOL_MIDP_OTA);
1011: } else {
1012: System.out.println("ERROR: Unknown URI type: " + uri);
1013: System.exit(0);
1014: }
1015:
1016: // Wait for either failure or success
1017: while (downloadFinished == false
1018: && downloadAborted == false) {
1019: System.out.println("waiting for download");
1020: try {
1021: Thread.sleep(100);
1022: } catch (java.lang.InterruptedException ie) {
1023: ie.printStackTrace();
1024: // Eat it
1025: }
1026: }
1027:
1028: // Some resolution
1029: if (!downloadFinished) {
1030: trace("Download failed!");
1031: return false;
1032: } else {
1033: trace("Download succeeded!");
1034: return true;
1035: }
1036: }
1037:
1038: void startDownload(String name, String uri, String protocol) {
1039: downloadFinished = false;
1040: downloadAborted = false;
1041:
1042: System.out.println("");
1043: System.out.println("==> Downloading: " + name);
1044:
1045: trace("Creating descriptor for " + uri);
1046:
1047: JUMPDownloadModule module = JUMPDownloadModuleFactory
1048: .getInstance().getModule(protocol);
1049:
1050: try {
1051:
1052: JUMPDownloadDescriptor descriptor = module
1053: .createDescriptor(uri);
1054: if (descriptor == null) {
1055: System.out
1056: .println("ERROR: Returned descriptor is NULL for "
1057: + uri);
1058: System.exit(0);
1059: }
1060:
1061: JUMPDownloader downloader = module
1062: .createDownloader(descriptor);
1063: JUMPDownloadDestination destination = new DownloadDestinationImpl(
1064: descriptor);
1065:
1066: // Trigger the download
1067: URL url = downloader.start(destination);
1068: trace("Download returns url: " + url);
1069:
1070: downloadFinished = true;
1071:
1072: descriptorVector.add(descriptor);
1073: urlVector.add(url);
1074: } catch (JUMPDownloadException o) {
1075: System.out.println("Download failed for " + uri);
1076: if (Verbose) {
1077: o.printStackTrace();
1078: }
1079: downloadAborted = true;
1080: } catch (Exception o) {
1081: System.out.println("Download failed for " + uri);
1082: if (Verbose) {
1083: o.printStackTrace();
1084: }
1085: downloadAborted = true;
1086: } finally {
1087: System.out.println("==> Finished Downloading: " + name);
1088: System.out.println("");
1089: }
1090: }
1091: }
1092:
1093: /**
1094: * The main method when used as a standalone tool.
1095: * @param args program args. See docs for details.
1096: */
1097: public static void main(String[] args) {
1098: new JUMPInstallerTool(args);
1099: }
1100: }
|