
org.xwiki.extension.job.internal.UpgradePlanJob Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xwiki-commons-extension-api Show documentation
Show all versions of xwiki-commons-extension-api Show documentation
XWiki Commons - Extension - API
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.extension.job.internal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.NavigableSet;
import java.util.TreeSet;
import javax.inject.Named;
import org.xwiki.component.annotation.Component;
import org.xwiki.extension.ExtensionId;
import org.xwiki.extension.InstallException;
import org.xwiki.extension.InstalledExtension;
import org.xwiki.extension.ResolveException;
import org.xwiki.extension.job.InstallRequest;
import org.xwiki.extension.repository.result.IterableResult;
import org.xwiki.extension.version.Version;
import org.xwiki.job.Request;
/**
* Create an Extension upgrade plan.
*
* @version $Id: 1de92db5be50754cc7b4f8c8329b42bc44b26c68 $
* @since 4.1M1
*/
@Component
@Named(UpgradePlanJob.JOBTYPE)
public class UpgradePlanJob extends AbstractInstallPlanJob
{
/**
* The id of the job.
*/
public static final String JOBTYPE = "upgradeplan";
@Override
public String getType()
{
return JOBTYPE;
}
@Override
protected InstallRequest castRequest(Request request)
{
InstallRequest installRequest;
if (request instanceof InstallRequest) {
installRequest = (InstallRequest) request;
} else {
installRequest = new InstallRequest(request);
}
return installRequest;
}
/**
* @param extension the extension currently installed
* @param namespace the namespace where the extension is installed
*/
protected void upgradeExtension(InstalledExtension extension, String namespace, boolean filterDependencies)
{
if (!getRequest().getExcludedExtensions().contains(extension.getId())
&& (!filterDependencies || !extension.isDependency(namespace))) {
NavigableSet versions = getVersions(extension, namespace);
// Useless to continue if the extension does not have any available version
if (!versions.isEmpty()) {
upgradeExtension(extension, namespace, versions.descendingSet());
}
}
}
private NavigableSet getVersions(InstalledExtension extension, String namespace)
{
NavigableSet versionList = new TreeSet<>();
// Search local versions
try {
IterableResult versions =
this.localExtensionRepository.resolveVersions(extension.getId().getId(), 0, -1);
for (Version version : versions) {
versionList.add(version);
}
} catch (ResolveException e) {
this.logger.debug("Failed to resolve local versions for extension id [{}]", extension.getId().getId(), e);
}
// Search remote versions
try {
IterableResult versions = this.repositoryManager.resolveVersions(extension.getId().getId(), 0, -1);
for (Version version : versions) {
versionList.add(version);
}
} catch (ResolveException e) {
this.logger.debug("Failed to resolve remote versions for extension id [{}]", extension.getId().getId(), e);
}
// Make sure the current version is included if the extension is invalid (it's possible this version does
// not exist on any repository)
if (!extension.isValid(namespace)) {
versionList.add(extension.getId().getVersion());
}
return versionList;
}
protected void upgradeExtension(InstalledExtension extension, String namespace, Collection versionList)
{
for (Version version : versionList) {
// Don't try to upgrade for lower versions but try to repair same version of the extension is invalid
int compare = extension.getId().getVersion().compareTo(version);
if (compare > 0 || (compare == 0 && extension.isValid(namespace))) {
break;
}
// Only upgrade beta if the current is beta etc.
if (extension.getId().getVersion().getType().ordinal() <= version.getType().ordinal()) {
if (tryInstallExtension(new ExtensionId(extension.getId().getId(), version), namespace)) {
break;
}
}
}
}
/**
* Try to install the provided extension and update the plan if it's working.
*
* @param extensionId the extension version to install
* @param namespace the namespace where to install the extension
* @return true if the installation would succeed, false otherwise
*/
protected boolean tryInstallExtension(ExtensionId extensionId, String namespace)
{
ModifableExtensionPlanTree currentTree = this.extensionTree.clone();
try {
installExtension(extensionId, namespace, currentTree);
setExtensionTree(currentTree);
return true;
} catch (InstallException e) {
this.logger.debug("Can't install extension [{}] on namespace [{}].", extensionId, namespace, e);
}
return false;
}
protected void upgrade(String namespace, Collection installedExtensions,
boolean filterDependencies)
{
this.progressManager.pushLevelProgress(installedExtensions.size(), this);
try {
for (InstalledExtension installedExtension : installedExtensions) {
this.progressManager.startStep(this);
if (namespace == null || !installedExtension.isInstalled(null)) {
upgradeExtension(installedExtension, namespace, filterDependencies);
}
}
} finally {
this.progressManager.popLevelProgress(this);
}
}
protected void upgrade(Collection installedExtensions, boolean filterDependencies)
{
this.progressManager.pushLevelProgress(installedExtensions.size(), this);
try {
for (InstalledExtension installedExtension : installedExtensions) {
this.progressManager.startStep(this);
if (installedExtension.getNamespaces() == null) {
upgradeExtension(installedExtension, null, filterDependencies);
} else {
this.progressManager.pushLevelProgress(installedExtension.getNamespaces().size(), this);
try {
for (String namespace : installedExtension.getNamespaces()) {
this.progressManager.startStep(this);
upgradeExtension(installedExtension, namespace, filterDependencies);
}
} finally {
this.progressManager.popLevelProgress(this);
}
}
}
} finally {
this.progressManager.popLevelProgress(this);
}
}
protected Collection getInstalledExtensions(String namespace)
{
Collection requestExtensions = getRequest().getExtensions();
Collection installedExtensions;
if (requestExtensions != null && !requestExtensions.isEmpty()) {
installedExtensions = new ArrayList<>(requestExtensions.size());
for (ExtensionId requestExtension : requestExtensions) {
InstalledExtension installedExtension =
this.installedExtensionRepository.getInstalledExtension(requestExtension);
if (installedExtension.isInstalled(namespace)) {
installedExtensions.add(installedExtension);
}
}
} else {
installedExtensions = this.installedExtensionRepository.getInstalledExtensions(namespace);
}
return installedExtensions;
}
protected Collection getInstalledExtensions()
{
Collection requestExtensions = getRequest().getExtensions();
Collection installedExtensions;
if (requestExtensions != null && !requestExtensions.isEmpty()) {
installedExtensions = new ArrayList<>(requestExtensions.size());
for (ExtensionId requestExtension : requestExtensions) {
InstalledExtension installedExtension =
this.installedExtensionRepository.getInstalledExtension(requestExtension);
installedExtensions.add(installedExtension);
}
} else {
installedExtensions = this.installedExtensionRepository.getInstalledExtensions();
}
return installedExtensions;
}
@Override
protected void runInternal() throws Exception
{
Collection namespaces = getRequest().getNamespaces();
Collection requestExtensions = getRequest().getExtensions();
boolean filterDependencies = requestExtensions == null || requestExtensions.isEmpty();
if (namespaces == null) {
Collection installedExtensions = getInstalledExtensions();
upgrade(installedExtensions, filterDependencies);
} else {
this.progressManager.pushLevelProgress(namespaces.size(), this);
try {
for (String namespace : namespaces) {
this.progressManager.startStep(this);
upgrade(namespace, getInstalledExtensions(namespace), filterDependencies);
}
} finally {
this.progressManager.popLevelProgress(this);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy