blob: 77093fe300ebad328b9d5f729862d4a01718e40b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.autoupdate.services;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import org.netbeans.Module;
import org.netbeans.ModuleManager;
import org.netbeans.api.autoupdate.UpdateElement;
import org.netbeans.api.autoupdate.UpdateManager;
import org.netbeans.api.autoupdate.UpdateManager.TYPE;
import org.netbeans.api.autoupdate.UpdateUnit;
import org.openide.modules.ModuleInfo;
import static org.netbeans.modules.autoupdate.services.Bundle.*;
import org.openide.util.NbBundle.Messages;
public class ModuleUpdateUnitImpl extends UpdateUnitImpl {
private UpdateUnit visibleAncestor;
public ModuleUpdateUnitImpl (String codename) {
super (codename);
}
@Override
public TYPE getType () {
return UpdateManager.TYPE.MODULE;
}
@Override
public boolean isPending () {
return UpdateUnitFactory.getDefault().isScheduledForRestart (getUpdateUnit ());
}
@Messages("broad_category=Libraries, Bridges, Uncategorized")
private static String BROAD_CATEGORY = broad_category();
@Override
public UpdateUnit getVisibleAncestor() {
if (visibleAncestor == null) {
assert getInstalled() != null : this + " is installed";
ModuleUpdateElementImpl installedImpl = (ModuleUpdateElementImpl) Trampoline.API.impl(getInstalled());
TreeSet<Module> visible = new TreeSet<Module> (new Comparator<Module> () {
@Override
public int compare(Module o1, Module o2) {
return o1.getCodeNameBase().compareTo(o2.getCodeNameBase());
}
});
Set<Module> seen = new HashSet<Module> ();
for (ModuleInfo mi : installedImpl.getModuleInfos()) {
visible.addAll(findVisibleAncestor(Utilities.toModule(mi), seen));
}
String cat = installedImpl.getCategory();
String installationCluster = installedImpl.getInstallationCluster();
if (BROAD_CATEGORY.contains(cat)) {
cat = null;
}
UpdateUnit shot = null;
UpdateUnit spare = null;
UpdateUnit strike = null;
for (Module visMod : visible) {
visibleAncestor = Utilities.toUpdateUnit(visMod);
UpdateElementImpl visibleImpl = Trampoline.API.impl(visibleAncestor.getInstalled());
String visTargetCluster = null;
String visCat = null;
if (visibleImpl != null && visibleImpl instanceof ModuleUpdateElementImpl) {
visTargetCluster = ((ModuleUpdateElementImpl) visibleImpl).getInstallationCluster();
visCat = visibleImpl.getCategory();
}
if (installationCluster != null && installationCluster.equals(visTargetCluster)) {
spare = visibleAncestor;
} else if (visCat != null && visCat.equals(cat)) {
strike = visibleAncestor;
break;
} else if (shot == null) {
shot = visibleAncestor;
}
}
visibleAncestor = strike != null ? strike : spare != null ? spare : shot;
// if it's still unknown - try visible representative in given cluster
if (visibleAncestor == null && installationCluster != null) {
for (UpdateElement visEl : UpdateManagerImpl.getInstance().getInstalledKits(installationCluster)) {
visibleAncestor = visEl.getUpdateUnit();
if (installedImpl.getRawCategory().equals(visEl.getCategory())) {
visibleAncestor = visEl.getUpdateUnit();
break;
}
}
}
}
return visibleAncestor;
}
private static Set<Module> findVisibleAncestor(Module module, Set<Module> seen) {
if (! seen.add(module)) {
return Collections.EMPTY_SET;
}
Set<Module> visible = new HashSet<Module> ();
ModuleManager manager = module.getManager();
Set<Module> moduleInterdependencies = manager.getModuleInterdependencies(module, ! module.isEager(), false, true);
for (Module m : moduleInterdependencies) {
if (m.isEnabled() && Utilities.isKitModule(m)) {
visible.add(m);
}
}
if (visible.isEmpty()) {
for (Module m : moduleInterdependencies) {
if (! m.isEnabled()) {
continue;
}
assert ! module.equals(m) : m + " cannot depend on itself.";
if (module.equals(m)) {
continue;
}
visible.addAll(findVisibleAncestor(m, seen));
if (! visible.isEmpty()) {
break;
}
}
}
TreeSet<Module> res = new TreeSet<Module>(new Comparator<Module>() {
@Override
public int compare(Module o1, Module o2) {
return o1.getCodeNameBase().compareTo(o2.getCodeNameBase());
}
});
res.addAll(visible);
return res;
}
}