// TODO: support question/answer with the UI to resolve conflicts
  @Override
  public void upgrade(
      LocalExtension previousLocalExtension, LocalExtension newLocalExtension, String namespace)
      throws InstallException {
    // TODO
    // 1) find all modified pages between old and new version
    // 2) compare old version and wiki (to find pages modified by user)
    // 3) delete pages removed in new version (even if modified ?)
    // 4) merge xar
    // 4.1) merge modified pages in wiki with diff between old/new version
    // 4.2) update unmodified pages different between old and new version

    // CURRENT

    XarLocalExtension previousXarExtension;
    try {
      previousXarExtension =
          (XarLocalExtension) this.xarRepository.resolve(previousLocalExtension.getId());
    } catch (ResolveException e) {
      // Not supposed to be possible
      throw new InstallException(
          "Failed to get xar extension ["
              + previousLocalExtension.getId()
              + "] from xar repository",
          e);
    }

    // Install new pages
    install(previousXarExtension, newLocalExtension, namespace);

    // Uninstall old version pages not anymore in the new version
    Set<XarEntry> previousPages = new HashSet<XarEntry>(previousXarExtension.getPages());

    List<XarEntry> newPages;
    try {
      XarLocalExtension newXarExtension =
          (XarLocalExtension) this.xarRepository.resolve(newLocalExtension.getId());
      newPages = newXarExtension.getPages();
    } catch (ResolveException e) {
      try {
        newPages =
            this.packager.getEntries(new File(newLocalExtension.getFile().getAbsolutePath()));
      } catch (IOException e1) {
        throw new InstallException(
            "Failed to get xar extension [" + newLocalExtension.getId() + "] pages", e);
      }
    }

    for (XarEntry entry : newPages) {
      previousPages.remove(entry);
    }

    try {
      this.packager.unimportPages(previousPages, namespace);
    } catch (Exception e) {
      this.logger.warn(
          "Exception when cleaning pages removed since previous xar extension version", e);
    }
  }
  /**
   * Check that the extension is properly reported to be not installed in the given namespace.
   *
   * @param localExtension the local extension to check
   * @param namespace the namespace where it should not be installed
   */
  private void ckeckUninstallStatus(LocalExtension localExtension, String namespace) {
    // check extension status
    Assert.assertFalse(DefaultInstalledExtension.isInstalled(localExtension, namespace));
    Assert.assertFalse(DefaultInstalledExtension.isInstalled(localExtension, null));

    // check repository status
    Assert.assertNull(
        this.installedExtensionRepository.getInstalledExtension(
            localExtension.getId().getId(), namespace));
    Assert.assertNull(
        this.installedExtensionRepository.getInstalledExtension(
            localExtension.getId().getId(), null));
  }
  @Override
  public void install(LocalExtension localExtension, String namespace) throws InstallException {
    ExtensionURLClassLoader classLoader =
        this.jarExtensionClassLoader.getURLClassLoader(namespace, true);

    // 1) load jar into classloader
    try {
      classLoader.addURL(localExtension.getFile().toURI().toURL());
    } catch (MalformedURLException e) {
      throw new InstallException("Failed to load jar file", e);
    }

    // 2) load and register components
    loadComponents(localExtension.getFile(), classLoader);
  }
  public void uninstall(LocalExtension localExtension, String namespace) throws UninstallException {
    // TODO: delete pages from the wiki which belong only to this extension (several extension could
    // have some
    // common pages which will cause all sort of other issues but still could happen technically)

    // TODO: maybe remove only unmodified page ? At least ask for sure when question/answer system
    // will be
    // implemented

    try {
      XarLocalExtension xarLocalExtension =
          (XarLocalExtension) this.xarRepository.resolve(localExtension.getId());
      List<XarEntry> pages = xarLocalExtension.getPages();
      this.packager.unimportPages(pages, namespace);
    } catch (Exception e) {
      // Not supposed to be possible
      throw new UninstallException(
          "Failed to get xar extension [" + localExtension.getId() + "] from xar repository", e);
    }
  }
Example #5
0
  private void registerExtension(XWikiContext context) {
    // Register the package as extension if it's one
    if (isInstallExension()
        && StringUtils.isNotEmpty(getExtensionId())
        && StringUtils.isNotEmpty(getVersion())) {
      ExtensionId extensionId = new ExtensionId(getExtensionId(), getVersion());

      try {
        LocalExtensionRepository localRepository =
            Utils.getComponent(LocalExtensionRepository.class);

        LocalExtension localExtension = localRepository.getLocalExtension(extensionId);
        if (localExtension == null) {
          Extension extension;
          try {
            // Try to find and download the extension from a repository
            extension = Utils.getComponent(ExtensionRepositoryManager.class).resolve(extensionId);
          } catch (ResolveException e) {
            LOGGER.debug("Can't find extension [{}]", extensionId, e);

            // FIXME: Create a dummy extension. Need support for partial/lazy extension.
            return;
          }

          localExtension = localRepository.storeExtension(extension);
        }

        // Register the extension as installed
        InstalledExtensionRepository installedRepository =
            Utils.getComponent(InstalledExtensionRepository.class);
        String namespace = "wiki:" + context.getWikiId();
        InstalledExtension installedExtension =
            installedRepository.getInstalledExtension(localExtension.getId());
        if (installedExtension == null || !installedExtension.isInstalled(namespace)) {
          installedRepository.installExtension(localExtension, namespace, false);
        }
      } catch (Exception e) {
        LOGGER.error("Failed to register extenion [{}] from the XAR", extensionId, e);
      }
    }
  }
  @Override
  public void uninstall(LocalExtension localExtension, String namespace) throws UninstallException {
    ExtensionURLClassLoader classLoader =
        this.jarExtensionClassLoader.getURLClassLoader(namespace, false);

    if (namespace == null || classLoader.getWiki().equals(namespace)) {
      // unregister components
      unloadComponents(localExtension.getFile(), classLoader);

      // TODO: find a way to unload the jar from the classloader
    }
  }
  /**
   * {@inheritDoc}
   *
   * @see
   *     org.xwiki.extension.handler.ExtensionHandlerManager#install(org.xwiki.extension.LocalExtension,
   *     java.lang.String)
   */
  public void install(LocalExtension localExtension, String namespace) throws InstallException {
    ExtensionHandler extensionHandler;
    try {
      // Load extension
      extensionHandler = getExtensionHandler(localExtension);
    } catch (ComponentLookupException e) {
      throw new InstallException(LOOKUPERROR + '[' + localExtension + ']', e);
    }

    try {
      extensionHandler.install(localExtension, namespace);
    } catch (Exception e) {
      // TODO: cleanup

      throw new InstallException("Failed to install extension [" + localExtension.getId() + "]", e);
    }
  }
  public void install(
      XarLocalExtension previousExtension, LocalExtension localExtension, String wiki)
      throws InstallException {
    // TODO: should be configurable
    MergeConfiguration mergeConfiguration = new MergeConfiguration();

    // import xar into wiki (add new version when the page already exists)
    try {
      this.packager.importXAR(
          previousExtension != null
              ? new XarFile(
                  new File(previousExtension.getFile().getAbsolutePath()),
                  previousExtension.getPages())
              : null,
          new File(localExtension.getFile().getAbsolutePath()),
          wiki,
          mergeConfiguration);
    } catch (Exception e) {
      throw new InstallException("Failed to import xar for extension [" + localExtension + "]", e);
    }
  }
 /**
  * Get the handler corresponding to the provided extension.
  *
  * @param localExtension the extension to handler
  * @return the handler
  * @throws ComponentLookupException failed to find a proper handler for the provided extension
  */
 private ExtensionHandler getExtensionHandler(LocalExtension localExtension)
     throws ComponentLookupException {
   // Load extension
   return this.componentManager.lookup(
       ExtensionHandler.class, localExtension.getType().toString().toLowerCase());
 }