// 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); } }
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()); }