public boolean pkgReset() {
   CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_RESET);
   if ("ask".equalsIgnoreCase(accept)) {
     accept =
         readConsole(
             "The reset will erase Marketplace packages history.\n"
                 + "Do you want to continue (yes/no)? [yes] ",
             "yes");
   }
   if (!Boolean.parseBoolean(accept)) {
     cmdInfo.exitCode = 1;
     return false;
   }
   try {
     service.reset();
     log.info("Packages reset done: all packages were marked as DOWNLOADED");
     List<LocalPackage> localPackages = service.getPackages();
     for (LocalPackage localPackage : localPackages) {
       localPackage.getUninstallFile().delete();
       FileUtils.deleteDirectory(localPackage.getData().getEntry(LocalPackage.BACKUP_DIR));
       newPackageInfo(cmdInfo, localPackage);
     }
     service.getRegistry().delete();
     FileUtils.deleteDirectory(service.getBackupDir());
   } catch (PackageException e) {
     log.error(e);
     cmdInfo.exitCode = 1;
   } catch (IOException e) {
     log.error(e);
     cmdInfo.exitCode = 1;
   }
   return cmdInfo.exitCode == 0;
 }
 /**
  * Add a package file into the cache
  *
  * @param packageFileName
  * @return The added LocalPackage or null if failed
  */
 public LocalPackage pkgAdd(String packageFileName) {
   CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_ADD);
   cmdInfo.param = packageFileName;
   LocalPackage pkg = null;
   try {
     File fileToAdd = getLocalPackageFile(packageFileName);
     if (fileToAdd == null) {
       String pkgId = getRemotePackageId(packageFileName);
       if (pkgId == null) {
         throw new PackageException(
             "Couldn't find a remote or local (relative to "
                 + "current directory or to NUXEO_HOME) "
                 + "package with name or ID "
                 + packageFileName);
       } else if (!downloadPackages(Arrays.asList(new String[] {pkgId}))) {
         throw new PackageException("Couldn't download package " + pkgId);
       }
       pkg = service.getPackage(pkgId);
       if (pkg == null) {
         throw new PackageException("Couldn't find downloaded package in cache " + pkgId);
       }
     } else {
       log.info("Adding " + packageFileName);
       pkg = service.addPackage(fileToAdd);
     }
     newPackageInfo(cmdInfo, pkg);
   } catch (Exception e) {
     cmdInfo.exitCode = 1;
     cmdInfo.newMessage(e);
   }
   return pkg;
 }
 public void pkgList(List<? extends Package> packagesList) {
   CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_LIST);
   try {
     if (packagesList.isEmpty()) {
       log.info("None");
     } else {
       NuxeoConnectClient.getPackageManager().sort(packagesList);
       StringBuilder sb = new StringBuilder();
       for (Package pkg : packagesList) {
         newPackageInfo(cmdInfo, pkg);
         String packageDescription = PackageState.getByValue(pkg.getState()).getLabel();
         packageDescription = String.format("%6s %11s\t", pkg.getType(), packageDescription);
         if (pkg.getState() == PackageState.REMOTE.getValue()
             && pkg.getType() != PackageType.STUDIO
             && pkg.getVisibility() != PackageVisibility.PUBLIC
             && !LogicalInstanceIdentifier.isRegistered()) {
           packageDescription += "Registration required for ";
         }
         packageDescription += String.format("%s (id: %s)\n", pkg.getName(), pkg.getId());
         sb.append(packageDescription);
       }
       log.info(sb.toString());
     }
   } catch (Exception e) {
     log.error(e);
     cmdInfo.exitCode = 1;
   }
 }
 /**
  * @param packages List of packages identified by their ID, name or local filename.
  * @since 5.7
  */
 public boolean pkgShow(List<String> packages) {
   boolean cmdOk = true;
   if (packages == null || packages.isEmpty()) {
     return cmdOk;
   }
   StringBuilder sb = new StringBuilder();
   sb.append("****************************************");
   for (String pkg : packages) {
     CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_SHOW);
     cmdInfo.param = pkg;
     try {
       PackageInfo packageInfo = newPackageInfo(cmdInfo, findPackage(pkg));
       sb.append("\nPackage: " + packageInfo.id);
       sb.append("\nState: " + packageInfo.state);
       sb.append("\nVersion: " + packageInfo.version);
       sb.append("\nName: " + packageInfo.name);
       sb.append("\nType: " + packageInfo.type);
       sb.append("\nVisibility: " + packageInfo.visibility);
       if (packageInfo.state == PackageState.REMOTE
           && packageInfo.type != PackageType.STUDIO
           && packageInfo.visibility != PackageVisibility.PUBLIC
           && !LogicalInstanceIdentifier.isRegistered()) {
         sb.append(" (registration required)");
       }
       sb.append("\nTarget platforms: " + ArrayUtils.toString(packageInfo.targetPlatforms));
       appendIfNotEmpty(sb, "\nVendor: ", packageInfo.vendor);
       sb.append("\nSupports hot-reload: " + packageInfo.supportsHotReload);
       sb.append("\nSupported: " + packageInfo.supported);
       sb.append("\nProduction state: " + packageInfo.productionState);
       sb.append("\nValidation state: " + packageInfo.validationState);
       appendIfNotEmpty(sb, "\nProvides: ", packageInfo.provides);
       appendIfNotEmpty(sb, "\nDepends: ", packageInfo.dependencies);
       appendIfNotEmpty(sb, "\nConflicts: ", packageInfo.conflicts);
       appendIfNotEmpty(sb, "\nTitle: ", packageInfo.title);
       appendIfNotEmpty(sb, "\nDescription: ", packageInfo.description);
       appendIfNotEmpty(sb, "\nHomepage: ", packageInfo.homePage);
       appendIfNotEmpty(sb, "\nLicense: ", packageInfo.licenseType);
       appendIfNotEmpty(sb, "\nLicense URL: ", packageInfo.licenseUrl);
       sb.append("\n****************************************");
     } catch (PackageException e) {
       cmdOk = false;
       cmdInfo.exitCode = 1;
       cmdInfo.newMessage(e);
     }
   }
   log.info(sb.toString());
   return cmdOk;
 }
 /**
  * Install a local package.
  *
  * @param pkgId Package ID or Name
  * @return The installed LocalPackage or null if failed
  */
 public LocalPackage pkgInstall(String pkgId) {
   if (env.getProperty(LAUNCHER_CHANGED_PROPERTY, "false").equals("true")) {
     System.exit(LAUNCHER_CHANGED_EXIT_CODE);
   }
   CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_INSTALL);
   cmdInfo.param = pkgId;
   try {
     LocalPackage pkg = getLocalPackage(pkgId);
     if (pkg == null) {
       // We don't know this package, try to add it first
       pkg = pkgAdd(pkgId);
     }
     if (pkg == null) {
       // Nothing worked - can't find the package anywhere
       throw new PackageException("Package not found: " + pkgId);
     }
     pkgId = pkg.getId();
     cmdInfo.param = pkgId;
     log.info("Installing " + pkgId);
     Task installTask = pkg.getInstallTask();
     try {
       performTask(installTask);
     } catch (PackageException e) {
       installTask.rollback();
       throw e;
     }
     // Refresh state
     pkg = service.getPackage(pkgId);
     newPackageInfo(cmdInfo, pkg);
     return pkg;
   } catch (Exception e) {
     log.error(String.format("Failed to install package: %s (%s)", pkgId, e.getMessage()));
     cmdInfo.exitCode = 1;
     cmdInfo.newMessage(e);
     return null;
   }
 }
 /**
  * Add a list of packages into the cache, downloading them if needed and possible.
  *
  * @param pkgsToAdd
  * @return true if command succeeded
  * @see #pkgAdd(String)
  */
 public boolean pkgAdd(List<String> pkgsToAdd) {
   boolean cmdOk = true;
   if (pkgsToAdd == null || pkgsToAdd.isEmpty()) {
     return cmdOk;
   }
   List<String> pkgIdsToDownload = new ArrayList<String>();
   for (String pkgToAdd : pkgsToAdd) {
     CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_ADD);
     cmdInfo.param = pkgToAdd;
     try {
       File fileToAdd = getLocalPackageFile(pkgToAdd);
       if (fileToAdd == null) {
         String pkgId = getRemotePackageId(pkgToAdd);
         if (pkgId == null) {
           throw new PackageException(
               "Couldn't find a remote or local (relative to "
                   + "current directory or to NUXEO_HOME) "
                   + "package with name or ID "
                   + pkgToAdd);
         } else {
           cmdInfo.newMessage(SimpleLog.LOG_LEVEL_INFO, "Waiting for download");
           pkgIdsToDownload.add(pkgId);
         }
       } else {
         log.info("Adding " + pkgToAdd);
         LocalPackage pkg = service.addPackage(fileToAdd);
         newPackageInfo(cmdInfo, pkg);
       }
     } catch (PackageException e) {
       cmdOk = false;
       cmdInfo.exitCode = 1;
       cmdInfo.newMessage(e);
     }
   }
   cmdOk = downloadPackages(pkgIdsToDownload) && cmdOk;
   return cmdOk;
 }
 /**
  * Uninstall a local package. The package is not removed from cache.
  *
  * @param pkgId Package ID or Name
  * @return The uninstalled LocalPackage or null if failed
  */
 public LocalPackage pkgUninstall(String pkgId) {
   if (env.getProperty(LAUNCHER_CHANGED_PROPERTY, "false").equals("true")) {
     System.exit(LAUNCHER_CHANGED_EXIT_CODE);
   }
   CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_UNINSTALL);
   cmdInfo.param = pkgId;
   try {
     LocalPackage pkg = service.getPackage(pkgId);
     if (pkg == null) {
       // Check whether this is the name of an installed package
       String realPkgId = getInstalledPackageIdFromName(pkgId);
       if (realPkgId != null) {
         pkgId = realPkgId;
         pkg = service.getPackage(realPkgId);
       }
     }
     if (pkg == null) {
       throw new PackageException("Package not found: " + pkgId);
     }
     log.info("Uninstalling " + pkgId);
     Task uninstallTask = pkg.getUninstallTask();
     try {
       performTask(uninstallTask);
     } catch (PackageException e) {
       uninstallTask.rollback();
       throw e;
     }
     // Refresh state
     pkg = service.getPackage(pkgId);
     newPackageInfo(cmdInfo, pkg);
     return pkg;
   } catch (Exception e) {
     log.error("Failed to uninstall package: " + pkgId, e);
     cmdInfo.exitCode = 1;
     return null;
   }
 }
 /**
  * Remove a package from cache. If it was installed, the package is uninstalled then removed.
  *
  * @param pkgId Package ID or Name
  * @return The removed LocalPackage or null if failed
  */
 public LocalPackage pkgRemove(String pkgId) {
   CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_REMOVE);
   cmdInfo.param = pkgId;
   try {
     LocalPackage pkg = service.getPackage(pkgId);
     if (pkg == null) {
       // Check whether this is the name of a local package
       String realPkgId = getLocalPackageIdFromName(pkgId);
       if (realPkgId != null) {
         pkgId = realPkgId;
         pkg = service.getPackage(realPkgId);
       }
     }
     if (pkg == null) {
       throw new PackageException("Package not found: " + pkgId);
     }
     if (pkg.getState() == PackageState.STARTED.getValue()
         || pkg.getState() == PackageState.INSTALLED.getValue()) {
       pkgUninstall(pkgId);
       // Refresh state
       pkg = service.getPackage(pkgId);
     }
     if (pkg.getState() != PackageState.DOWNLOADED.getValue()) {
       throw new PackageException(
           "Can only remove packages in DOWNLOADED, INSTALLED or STARTED state");
     }
     log.info("Removing " + pkgId);
     service.removePackage(pkgId);
     newPackageInfo(cmdInfo, pkg).state = PackageState.REMOTE;
     return pkg;
   } catch (Exception e) {
     log.error("Failed to remove package: " + pkgId, e);
     cmdInfo.exitCode = 1;
     return null;
   }
 }
 @SuppressWarnings("unused")
 protected boolean downloadPackages(List<String> packagesToDownload) {
   if (packagesToDownload == null) {
     return true;
   }
   List<String> packagesAlreadyDownloaded = new ArrayList<String>();
   for (String pkg : packagesToDownload) {
     try {
       if (getLocalPackage(pkg) != null) {
         log.info(String.format("Package %s is already in local cache", pkg));
         packagesAlreadyDownloaded.add(pkg);
       }
     } catch (PackageException e) {
       log.error(
           String.format("Looking for package %s in local cache raised an error. Aborting.", pkg),
           e);
       return false;
     }
   }
   packagesToDownload.removeAll(packagesAlreadyDownloaded);
   if (packagesToDownload.isEmpty()) {
     return true;
   }
   List<DownloadingPackage> pkgs = new ArrayList<DownloadingPackage>();
   // Queue downloads
   log.info("Downloading " + packagesToDownload + "...");
   for (String pkg : packagesToDownload) {
     try {
       pkgs.add(getPackageManager().download(pkg));
     } catch (Exception e) {
       log.error("Cannot download packages", e);
       return false;
     }
   }
   // Check progress
   boolean downloadOk = true;
   long startTime = new Date().getTime();
   long deltaTime = 0;
   do {
     List<DownloadingPackage> pkgsCompleted = new ArrayList<DownloadingPackage>();
     for (DownloadingPackage pkg : pkgs) {
       if (pkg.isCompleted()) {
         pkgsCompleted.add(pkg);
         CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_DOWNLOAD);
         cmdInfo.param = pkg.getId();
         // Digest check not correctly implemented
         if (false && !pkg.isDigestOk()) {
           downloadOk = false;
           cmdInfo.exitCode = 1;
           cmdInfo.newMessage(
               SimpleLog.LOG_LEVEL_ERROR, "Wrong digest for package " + pkg.getName());
         } else if (pkg.getState() == PackageState.DOWNLOADED.getValue()) {
           cmdInfo.newMessage(SimpleLog.LOG_LEVEL_DEBUG, "Downloaded " + pkg);
         } else {
           downloadOk = false;
           cmdInfo.exitCode = 1;
           cmdInfo.newMessage(
               SimpleLog.LOG_LEVEL_ERROR,
               String.format("Download failed for %s. %s", pkg, pkg.getErrorMessage()));
         }
       }
     }
     pkgs.removeAll(pkgsCompleted);
     deltaTime = (new Date().getTime() - startTime) / 1000;
   } while (deltaTime < PACKAGES_DOWNLOAD_TIMEOUT_SECONDS && pkgs.size() > 0);
   // Timeout (not everything get downloaded)?
   if (pkgs.size() > 0) {
     downloadOk = false;
     log.error("Timeout while trying to download packages");
     for (DownloadingPackage pkg : pkgs) {
       CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_ADD);
       cmdInfo.param = pkg.getId();
       cmdInfo.exitCode = 1;
       cmdInfo.newMessage(SimpleLog.LOG_LEVEL_ERROR, "Download timeout for " + pkg);
     }
   }
   return downloadOk;
 }
 /**
  * @since 5.6
  * @param commandsFile File containing the commands to execute
  * @param doExecute Whether to execute or list the actions
  * @param useResolver Whether to use full resolution or just execute individual actions
  */
 @SuppressWarnings("unchecked")
 public boolean executePending(File commandsFile, boolean doExecute, boolean useResolver) {
   int errorValue = 0;
   if (!commandsFile.isFile()) {
     return false;
   }
   List<String> pkgsToAdd = new ArrayList<String>();
   List<String> pkgsToInstall = new ArrayList<String>();
   List<String> pkgsToUninstall = new ArrayList<String>();
   List<String> pkgsToRemove = new ArrayList<String>();
   List<String> lines;
   try {
     lines = FileUtils.readLines(commandsFile);
     for (String line : lines) {
       line = line.trim();
       String[] split = line.split("\\s+", 2);
       if (split.length == 2) {
         if (split[0].equals(CommandInfo.CMD_INSTALL)) {
           if (doExecute) {
             if (useResolver) {
               pkgsToInstall.add(split[1]);
             } else {
               pkgInstall(split[1]);
             }
           } else {
             CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_INSTALL);
             cmdInfo.param = split[1];
             cmdInfo.pending = true;
           }
         } else if (split[0].equals(CommandInfo.CMD_ADD)) {
           if (doExecute) {
             if (useResolver) {
               pkgsToAdd.add(split[1]);
             } else {
               pkgAdd(split[1]);
             }
           } else {
             CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_ADD);
             cmdInfo.param = split[1];
             cmdInfo.pending = true;
           }
         } else if (split[0].equals(CommandInfo.CMD_UNINSTALL)) {
           if (doExecute) {
             if (useResolver) {
               pkgsToUninstall.add(split[1]);
             } else {
               pkgUninstall(split[1]);
             }
           } else {
             CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_UNINSTALL);
             cmdInfo.param = split[1];
             cmdInfo.pending = true;
           }
         } else if (split[0].equals(CommandInfo.CMD_REMOVE)) {
           if (doExecute) {
             if (useResolver) {
               pkgsToRemove.add(split[1]);
             } else {
               pkgRemove(split[1]);
             }
           } else {
             CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_REMOVE);
             cmdInfo.param = split[1];
             cmdInfo.pending = true;
           }
         } else {
           errorValue = 1;
         }
       } else if (split.length == 1) {
         if (line.length() > 0 && !line.startsWith("#")) {
           if (doExecute) {
             if ("init".equals(line)) {
               if (!addDistributionPackages()) {
                 errorValue = 1;
               }
             } else {
               if (useResolver) {
                 pkgsToInstall.add(line);
               } else {
                 pkgInstall(line);
               }
             }
           } else {
             if ("init".equals(line)) {
               CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_INIT);
               cmdInfo.pending = true;
             } else {
               CommandInfo cmdInfo = cset.newCommandInfo(CommandInfo.CMD_INSTALL);
               cmdInfo.param = line;
               cmdInfo.pending = true;
             }
           }
         }
       }
       if (errorValue != 0) {
         log.error("Error processing pending package/command: " + line);
       }
     }
     if (doExecute) {
       if (useResolver) {
         String oldAccept = accept;
         String oldRelax = relax;
         accept = "true";
         relax = "true";
         boolean success = pkgRequest(pkgsToAdd, pkgsToInstall, pkgsToUninstall, pkgsToRemove);
         accept = oldAccept;
         relax = oldRelax;
         if (!success) {
           errorValue = 2;
         }
       }
       if (errorValue != 0) {
         File bak = new File(commandsFile.getPath() + ".bak");
         bak.delete();
         commandsFile.renameTo(bak);
       } else {
         commandsFile.delete();
       }
     } else {
       cset.log(true);
     }
   } catch (IOException e) {
     log.error(e.getMessage());
   }
   return errorValue == 0;
 }