Пример #1
0
  /**
   * Cleans the WAR file of all files relating to the currently installed version of the the AMP.
   *
   * @param warFileLocatio the war file location
   * @param moduleId the module id
   * @param preview indicates whether this is a preview installation
   */
  private void cleanWAR(String warFileLocation, String moduleId, boolean preview) {
    InstalledFiles installedFiles = new InstalledFiles(warFileLocation, moduleId);
    installedFiles.load();

    for (String add : installedFiles.getAdds()) {
      // Remove file
      removeFile(warFileLocation, add, preview);
    }
    for (String mkdir : installedFiles.getMkdirs()) {
      // Remove folder
      removeFile(warFileLocation, mkdir, preview);
    }
    for (Map.Entry<String, String> update : installedFiles.getUpdates().entrySet()) {
      if (preview == false) {
        // Recover updated file and delete backups
        File modified = new File(warFileLocation + update.getKey(), DETECTOR_AMP_AND_WAR);
        File backup = new File(warFileLocation + update.getValue(), DETECTOR_AMP_AND_WAR);
        modified.copyFrom(backup);
        backup.delete();
      }

      outputMessage(
          "Recovering file '" + update.getKey() + "' from backup '" + update.getValue() + "'",
          true);
    }
    // Now remove the installed files list
    String installedFilesPathInWar = installedFiles.getFilePathInWar();
    removeFile(warFileLocation, installedFilesPathInWar, preview);
    // Remove the module properties
    String modulePropertiesFileLocationInWar =
        ModuleDetailsHelper.getModulePropertiesFilePathInWar(moduleId);
    removeFile(warFileLocation, modulePropertiesFileLocationInWar, preview);
  }
Пример #2
0
  /**
   * Lists all the currently installed modules in the WAR
   *
   * @param warLocation the war location
   */
  public void listModules(String warLocation) {
    ModuleDetails moduleDetails = null;
    boolean previous = this.verbose;
    this.verbose = true;
    try {
      File moduleDir = new File(warLocation + MODULE_DIR, DETECTOR_AMP_AND_WAR);
      if (moduleDir.exists() == false) {
        outputMessage("No modules are installed in this WAR file");
      }

      java.io.File[] dirs = moduleDir.listFiles();
      if (dirs != null && dirs.length != 0) {
        for (java.io.File dir : dirs) {
          if (dir.isDirectory() == true) {
            File moduleProperties =
                new File(dir.getPath() + "/module.properties", DETECTOR_AMP_AND_WAR);
            if (moduleProperties.exists() == true) {
              try {
                InputStream is = new FileInputStream(moduleProperties);
                moduleDetails = ModuleDetailsHelper.createModuleDetailsFromPropertiesStream(is);
              } catch (IOException exception) {
                throw new ModuleManagementToolException(
                    "Unable to open module properties file '" + moduleProperties.getPath() + "'",
                    exception);
              }

              outputMessage(
                  "Module '" + moduleDetails.getId() + "' installed in '" + warLocation + "'");
              outputMessage("   Title:        " + moduleDetails.getTitle(), true);
              outputMessage("   Version:      " + moduleDetails.getVersion(), true);
              outputMessage("   Install Date: " + moduleDetails.getInstallDate(), true);
              outputMessage("   Description:   " + moduleDetails.getDescription(), true);
            }
          }
        }
      } else {
        outputMessage("No modules are installed in this WAR file");
      }
    } finally {
      this.verbose = previous;
    }
  }
  @Test
  public void testCheckCompatibleEditionUsingManifest() throws IOException {
    Properties props = dummyModuleProperties();
    ModuleDetails installingModuleDetails = new ModuleDetailsImpl(props);
    TFile theWar = getFile(".war", "module/share-3.4.11.war"); // enterprise edition

    // Test for no edition specified
    this.checkCompatibleEditionUsingManifest(
        theWar, installingModuleDetails); // does not throw exception

    // Test for invalid edition
    props.setProperty(ModuleDetails.PROP_EDITIONS, "CommuniT");
    installingModuleDetails = new ModuleDetailsImpl(props);
    try {
      this.checkCompatibleEditionUsingManifest(theWar, installingModuleDetails);
      fail(); // should never get here
    } catch (ModuleManagementToolException exception) {
      assertTrue(
          exception
              .getMessage()
              .endsWith("can only be installed in one of the following editions[CommuniT]"));
    }

    props.setProperty(ModuleDetails.PROP_EDITIONS, ("Enterprise")); // should ignore case
    installingModuleDetails = new ModuleDetailsImpl(props);
    this.checkCompatibleEditionUsingManifest(
        theWar, installingModuleDetails); // does not throw exception

    props.setProperty(ModuleDetails.PROP_EDITIONS, ("Community")); // should ignore case
    installingModuleDetails = new ModuleDetailsImpl(props);
    try {
      this.checkCompatibleEditionUsingManifest(theWar, installingModuleDetails);
      fail(); // should never get here
    } catch (ModuleManagementToolException exception) {
      assertTrue(
          exception
              .getMessage()
              .endsWith("can only be installed in one of the following editions[Community]"));
    }

    theWar = getFile(".war", "module/share-4.2.a.war");
    this.checkCompatibleEditionUsingManifest(theWar, installingModuleDetails);

    String propertiesLocation = getFile(".amp", "module/test_v5.amp") + "/module.properties";
    installingModuleDetails =
        ModuleDetailsHelper.createModuleDetailsFromPropertyLocation(propertiesLocation);

    try {
      this.checkCompatibleEdition(theWar, installingModuleDetails);
      fail(); // should never get here
    } catch (ModuleManagementToolException exception) {
      assertTrue(
          exception
              .getMessage()
              .endsWith("can only be installed in one of the following editions[Enterprise]"));
    }

    theWar = getFile(".war", "module/share-3.4.11.war");
    this.checkCompatibleEdition(theWar, installingModuleDetails); // should succeed

    try {
      theWar = getFile(".war", "module/share-4.2.a.war");
      this.checkCompatibleEdition(theWar, installingModuleDetails);
      fail(); // should never get here
    } catch (ModuleManagementToolException exception) {
      assertTrue(
          exception
              .getMessage()
              .endsWith("can only be installed in one of the following editions[Enterprise]"));
    }
  }
Пример #4
0
  /**
   * Installs a given AMP file into a given WAR file.
   *
   * @param ampFileLocation the location of the AMP file to be installed
   * @param warFileLocation the location of the WAR file into which the AMP file is to be installed.
   * @param preview indicates whether this should be a preview install. This means that the process
   *     of installation will be followed and reported, but the WAR file will not be modified.
   * @param forceInstall indicates whether the installed files will be replaces reguarless of the
   *     currently installed version of the AMP. Generally used during development of the AMP.
   * @param backupWAR indicates whether we should backup the war we are modifying or not
   */
  public void installModule(
      String ampFileLocation,
      String warFileLocation,
      boolean preview,
      boolean forceInstall,
      boolean backupWAR) {
    try {
      outputMessage("Installing AMP '" + ampFileLocation + "' into WAR '" + warFileLocation + "'");

      if (preview == false) {
        // Make sure the module and backup directory exisits in the WAR file
        File moduleDir = new File(warFileLocation + MODULE_DIR, DETECTOR_AMP_AND_WAR);
        if (moduleDir.exists() == false) {
          moduleDir.mkdir();
        }
        File backUpDir = new File(warFileLocation + BACKUP_DIR, DETECTOR_AMP_AND_WAR);
        if (backUpDir.exists() == false) {
          backUpDir.mkdir();
        }

        // Make a backup of the war we are going to modify
        if (backupWAR == true) {
          java.io.File warFile = new java.io.File(warFileLocation);
          if (warFile.exists() == false) {
            throw new ModuleManagementToolException(
                "The war file '" + warFileLocation + "' does not exist.");
          }
          String backupLocation = warFileLocation + "-" + System.currentTimeMillis() + ".bak";
          java.io.File backup = new java.io.File(backupLocation);
          copyFile(warFile, backup);

          outputMessage("WAR has been backed up to '" + backupLocation + "'");
        }
      }

      // Get the details of the installing module
      String propertiesLocation = ampFileLocation + "/module.properties";
      ModuleDetails installingModuleDetails =
          ModuleDetailsHelper.createModuleDetailsFromPropertyLocation(propertiesLocation);
      if (installingModuleDetails == null) {
        throw new ModuleManagementToolException(
            "No module.properties file has been found in the installing .amp file '"
                + ampFileLocation
                + "'");
      }
      String installingId = installingModuleDetails.getId();
      VersionNumber installingVersion = installingModuleDetails.getVersion();

      // Check that the target war has the necessary dependencies for this install
      List<ModuleDependency> installingModuleDependencies =
          installingModuleDetails.getDependencies();
      List<ModuleDependency> missingDependencies = new ArrayList<ModuleDependency>(0);
      for (ModuleDependency dependency : installingModuleDependencies) {
        String dependencyId = dependency.getDependencyId();
        ModuleDetails dependencyModuleDetails =
            ModuleDetailsHelper.createModuleDetailsFromWarAndId(warFileLocation, dependencyId);
        // Check the dependency.  The API specifies that a null returns false, so no null check is
        // required
        if (!dependency.isValidDependency(dependencyModuleDetails)) {
          missingDependencies.add(dependency);
          continue;
        }
      }
      if (missingDependencies.size() > 0) {
        throw new ModuleManagementToolException(
            "The following modules must first be installed: " + missingDependencies);
      }

      // Try to find an installed module by the ID
      ModuleDetails installedModuleDetails =
          ModuleDetailsHelper.createModuleDetailsFromWarAndId(warFileLocation, installingId);
      if (installedModuleDetails == null) {
        // It might be there as one of the aliases
        List<String> installingAliases = installingModuleDetails.getAliases();
        for (String installingAlias : installingAliases) {
          ModuleDetails installedAliasModuleDetails =
              ModuleDetailsHelper.createModuleDetailsFromWarAndId(warFileLocation, installingAlias);
          if (installedAliasModuleDetails == null) {
            // There is nothing by that alias
            continue;
          }
          // We found an alias and will treat it as the same module
          installedModuleDetails = installedAliasModuleDetails;
          outputMessage(
              "Module '"
                  + installingAlias
                  + "' is installed and is an alias of '"
                  + installingId
                  + "'");
          break;
        }
      }

      // Now clean up the old instance
      if (installedModuleDetails != null) {
        String installedId = installedModuleDetails.getId();
        VersionNumber installedVersion = installedModuleDetails.getVersion();

        int compareValue = installedVersion.compareTo(installingVersion);
        if (forceInstall == true || compareValue == -1) {
          if (forceInstall == true) {
            // Warn of forced install
            outputMessage(
                "WARNING: The installation of this module is being forced.  All files will be removed and replaced regardless of exiting versions present.");
          }

          // Trying to update the extension, old files need to cleaned before we proceed
          outputMessage(
              "Clearing out files relating to version '"
                  + installedVersion
                  + "' of module '"
                  + installedId
                  + "'");
          cleanWAR(warFileLocation, installedId, preview);
        } else if (compareValue == 0) {
          // Trying to install the same extension version again
          outputMessage(
              "WARNING: This version of this module is already installed in the WAR. Installation skipped.");
          return;
        } else if (compareValue == 1) {
          // Trying to install an earlier version of the extension
          outputMessage(
              "WARNING: A later version of this module is already installed in the WAR. Installation skipped.");
          return;
        }
      }

      // Check if a custom mapping file has been defined
      Properties fileMappingProperties = null;
      Properties customFileMappingProperties = getCustomFileMappings(ampFileLocation);
      if (customFileMappingProperties == null) {
        fileMappingProperties = defaultFileMappingProperties;
      } else {
        fileMappingProperties = new Properties();
        // A custom mapping file was present.  Check if it must inherit the default mappings.
        String inheritDefaultStr =
            customFileMappingProperties.getProperty(PROP_INHERIT_DEFAULT, "true");
        if (inheritDefaultStr.equalsIgnoreCase("true")) {
          fileMappingProperties.putAll(defaultFileMappingProperties);
        }
        fileMappingProperties.putAll(customFileMappingProperties);
        fileMappingProperties.remove(PROP_INHERIT_DEFAULT);
      }

      // Copy the files from the AMP file into the WAR file
      outputMessage(
          "Adding files relating to version '"
              + installingVersion
              + "' of module '"
              + installingId
              + "'");
      InstalledFiles installedFiles = new InstalledFiles(warFileLocation, installingId);
      for (Map.Entry<Object, Object> entry : fileMappingProperties.entrySet()) {
        // The file mappings are expected to start with "/"
        String mappingSource = (String) entry.getKey();
        if (mappingSource.length() == 0 || !mappingSource.startsWith("/")) {
          throw new AlfrescoRuntimeException(
              "File mapping sources must start with '/', but was: " + mappingSource);
        }
        String mappingTarget = (String) entry.getValue();
        if (mappingTarget.length() == 0 || !mappingTarget.startsWith("/")) {
          throw new AlfrescoRuntimeException(
              "File mapping targets must start with '/' but was '" + mappingTarget + "'");
        }

        // Run throught the files one by one figuring out what we are going to do during the copy
        copyToWar(
            ampFileLocation,
            warFileLocation,
            mappingSource,
            mappingTarget,
            installedFiles,
            preview);

        if (preview == false) {
          // Get a reference to the source folder (if it isn't present don't do anything)
          File source = new File(ampFileLocation + "/" + mappingSource, DETECTOR_AMP_AND_WAR);
          if (source != null && source.list() != null) {
            // Get a reference to the destination folder
            File destination =
                new File(warFileLocation + "/" + mappingTarget, DETECTOR_AMP_AND_WAR);
            if (destination == null) {
              throw new ModuleManagementToolException(
                  "The destination folder '"
                      + mappingTarget
                      + "' as specified in mapping properties does not exist in the war");
            }
            // Do the bulk copy since this is quicker than copying files one by one
            destination.copyAllFrom(source);
          }
        }
      }

      if (preview == false) {
        // Save the installed file list
        installedFiles.save();

        // Update the installed module details
        installingModuleDetails.setInstallState(ModuleInstallState.INSTALLED);
        installingModuleDetails.setInstallDate(new Date());
        ModuleDetailsHelper.saveModuleDetails(warFileLocation, installingModuleDetails);

        // Update the zip files
        File.update();

        // Set the modified date
        java.io.File warFile = new java.io.File(warFileLocation);
        if (warFile.exists()) {
          warFile.setLastModified(System.currentTimeMillis());
        }
      }
    } catch (ZipWarningException ignore) {
      // Only instances of the class ZipWarningException exist in the chain of
      // exceptions. We choose to ignore this.
    } catch (ZipControllerException exception) {
      // At least one exception occured which is not just a ZipWarningException.
      // This is a severe situation that needs to be handled.
      throw new ModuleManagementToolException(
          "A Zip error was encountered during deployment of the AEP into the WAR", exception);
    } catch (IOException exception) {
      throw new ModuleManagementToolException(
          "An IO error was encountered during deployment of the AEP into the WAR", exception);
    }
  }